How to check if an object inherits from a common base class without knowing the typeparam

I have the following construct for classes:

public class Request : BaseRequest, IRequestFromResponse
{
}

      

which defines the object Request

to be submitted via the html form.

Model

where Request

lives in build up, for example:

public class Response : BaseRequestWrapperResponse<Request>
{
}

      

and BaseWrapper:

public abstract class BaseRequestWrapperResponse<TRequest> where TRequest : IRequestFromResponse
{
    public TRequest Request { get; set; }
}

      

IRequestFromResponse

is just an empty marker interface.

I am trying to start an object at runtime, so I have access to Request

-property BaseRequestWrapperResponse

.

All I have so far:

var model = ((ViewContext) context).ViewData.Model;

if (model.GetType().IsSubclassOf(typeof (BaseRequestWrapperResponse<IRequestFromResponse>)))
// if (model.GetType().BaseClass.IsAssignableFrom(typeof (BaseRequestWrapperResponse<IRequestFromResponse>)))
// if (model.GetType().IsSubclassOf(typeof (BaseRequestWrapperResponse<>)))
// if (model.GetType().BaseClass.IsAssignableFrom(typeof (BaseRequestWrapperResponse<>)))
{
    model = ((BaseRequestWrapperResponse<IRequestFromResponse>) model).Request;
}

      

I can't get a check that indicates that Model

is kind BaseRequestWrapperResponse

. Then throwing will be my next problem.

+3


source to share


3 answers


How to add a non-generic class BaseRequestWrapperResponse

.

public abstract class BaseRequestWrapperResponse 
{
    public IRequestFromResponse Request { get; set; }
}

public abstract class BaseRequestWrapperResponse<TRequest> : BaseRequestWrapperResponse where TRequest : IRequestFromResponse
{
    public new TRequest Request
    {
        get{ return (TRequest)base.Request; }
        set{ base.Request = value; }
    }
}

      



Then just:

model = ((BaseRequestWrapperResponse) model).Request;

      

+1


source


This doesn't work because the only types the model is in are Response

and BaseRequestWrapperResponse<Request>

.

You must understand that generic types are concrete types as soon as you insert a type argument. Since it Request

inherits from BaseRequestWrapperResponse<Request>

, this BaseRequestWrapperResponse<Request>

is an actual type that has no inheritance relationship to BaseRequestWrapperResponse<TRequest>

. Its just kind - a copy with a type argument put it in.

You might see generic types more as templates for actual types that are created when you type in a generic type. So when you used BaseRequestWrapperResponse<Request>

, you actually defined the following type:

public abstract class BaseRequestWrapperResponse_Request
{
    public Request Request { get; set; }
}

      



And there is nothing to do with the generic type and information about its generic type argument.

If you want to access an object Request

, you have to add it to the generic interface eg. IResponse

which then implements your abstract generic type:

public interface IResponse
{
    IRequestFromResponse Request { get; set; }
}

      

This will at least allow you to access the request object, although you will have to use it anyway.

0


source


Try:

var model = ((ViewContext) context).ViewData.Model;
var modelType = model.GetType();

if (modelType .GetGenericArguments()[0] == typeof (Request)) 
&& 
modelType.GetGenericTypeDefinition().IsAssignableFrom(typeof(BaseRequestWrapperResponse<>)) 
{
    model = ((BaseRequestWrapperResponse<Request>) model).Request;
}

      

Note that BaseRequestWrapperResponse does not inherit from BaseRequestWrapperResponse even though Request inherits from IRequestFromResponse, so you cannot do:

if (modelType .GetGenericArguments()[0].IsAssignableFrom(typeof(IRequestFromResponse)) && 
    modelType.GetGenericTypeDefinition().IsAssignableFrom(typeof(BaseRequestWrapperResponse<>)) 
    {
        model = ((BaseRequestWrapperResponse<IRequestFromResponse>) model).Request;
    }

      

if the generic model is actually BaseRequestWrapperResponse

0


source







All Articles