Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C# Access instance of generic type argument at runtime

I have a handle exception method for my Polly IAsyncPolicy defined as such:

Handle<ApiException>(ApiException ex)
{
 /// do stuff
} 

An ApiException can be either generic or non-generic:

public class ApiException

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

and

public class ApiException<TResult>

I know that an instance of the generic type will have a Property called Result of type TResult, which will always inherit from a type called BaseResponse.

There are many many classes that inherit from BaseResponse. I want to avoid having to write exception handlers for them all and do it all in the one handler.

At runtime, I want to

a) determine that ex is either a generic or non-generic instance of ApiException and

b) get a reference to the instance if it is generic, and access the "Result" property

I can do a) easily enough with ex.GetType().IsGenericType

b) is proving troublesome

I have tried:

        if (ex is ApiException<> apiE)
        {

        }

But I need a type to go in the <>

I know that type will always inherit from a type called BaseResponse so I tried,

        if (ex is ApiException<BaseResponse> apiE)
        {

        }

but it’s not specific enough and returns false for child inheritors e.g ApiException<AuthResponse> where AuthResponse : BaseResponse

Is there anything that can be done?

>Solution :

You can indeed get the type of the generic parameter, you can also read that Result using reflection. Whether you can do anything meaningful with it kind of depends.

static void Handle<T>(T ex) where T : ApiException
{
    var type = typeof(T);
    if(!type.IsGenericType)
    {
        Console.WriteLine($"{type} is non generic");
    }
    else
    {
        var gType = type.GetGenericArguments()[0];
        Console.WriteLine($"{type} is generic, the type is {gType}");
        
        var result = type.GetProperty("Result");
        var obj = (BaseResponse)result.GetValue(ex);
        Console.WriteLine($"Got Result={obj.Name}");
    }
        
}

Live example: https://dotnetfiddle.net/DpyZpk


My "It depends" comment was before I noticed that you commented

I only need to access properties on the base TBaseResult which all TResults will inherit from

So you’re in luck…. you can cast that Result

var obj = (BaseResponse)result.GetValue(ex);
// You can call any methods/properties on the base  type
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading