Reputation: 3841
I have the following construct for classes:
public class Request : BaseRequest, IRequestFromResponse
{
}
which defines a Request
-object to be posted via html form.
The Model
, where the Request
lives in build up like:
public class Response : BaseRequestWrapperResponse<Request>
{
}
while the BaseWrapper is build:
public abstract class BaseRequestWrapperResponse<TRequest> where TRequest : IRequestFromResponse
{
public TRequest Request { get; set; }
}
IRequestFromResponse
is just an empty marker-interface.
I try to cast the object at runtime, so I have access to the Request
-property of BaseRequestWrapperResponse
.
All I have so far is:
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'm not able to get a check which indicates that model
is some sort of BaseRequestWrapperResponse
. The cast would then be my next problem.
Upvotes: 3
Views: 624
Reputation: 179
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 if Request inherits from IRequestFromResponse, therefore you cannot do:
if (modelType .GetGenericArguments()[0].IsAssignableFrom(typeof(IRequestFromResponse)) &&
modelType.GetGenericTypeDefinition().IsAssignableFrom(typeof(BaseRequestWrapperResponse<>))
{
model = ((BaseRequestWrapperResponse<IRequestFromResponse>) model).Request;
}
if model's generic is actually BaseRequestWrapperResponse
Upvotes: 0
Reputation: 46987
How about adding a non generic BaseRequestWrapperResponse
class.
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;
Upvotes: 1
Reputation: 388253
This won’t work because the only types that the model is of is Response
and BaseRequestWrapperResponse<Request>
.
You have to understand that generic types are concrete types as soon as you put the type argument in. So since Request
inherits from BaseRequestWrapperResponse<Request>
, that BaseRequestWrapperResponse<Request>
is an actual type that has no inheritance relationship to BaseRequestWrapperResponse<TRequest>
. It’s just kind-of a copy with the type argument placed it.
You could see generic types more as templates for the actual types that are created when you put a generic type in. 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 no relationship to the generic type, and the information about its generic type argument.
If you want to access the Request
object, you should add it to a common interface, e.g. IResponse
, which your abstract generic type then implements:
public interface IResponse
{
IRequestFromResponse Request { get; set; }
}
That will at least allow you to access the request object—although you may still have to cast it.
Upvotes: 0