如何在不知道typeparam类型的情况下检查对象是否继承自泛型基类



我有下面的类结构:

public class Request : BaseRequest, IRequestFromResponse
{
}

定义了一个Request -object通过html表单发布。

Request所在的Model积聚如下:

public class Response : BaseRequestWrapperResponse<Request>
{
}

当BaseWrapper被构建时:

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

IRequestFromResponse只是一个空的标记接口。

我尝试在运行时强制转换对象,所以我可以访问BaseRequestWrapperResponseRequest -属性。

我现在只知道:

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;
}

我不能得到一个检查,表明model是某种BaseRequestWrapperResponse。转换将是我的下一个问题。

添加一个非通用的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; }
    }
}

然后:

model = ((BaseRequestWrapperResponse) model).Request;

这不起作用,因为模型的唯一类型是ResponseBaseRequestWrapperResponse<Request>

你必须明白,泛型类型是具体类型一旦你把类型参数。因此,由于Request继承自BaseRequestWrapperResponse<Request>,因此BaseRequestWrapperResponse<Request>是与BaseRequestWrapperResponse<TRequest>没有继承关系的实际类型。它只是一种带有类型参数的复制。

您可以更多地将泛型类型视为模板,用于在放入泛型类型时创建的实际类型。所以当你使用BaseRequestWrapperResponse<Request>时,你实际上定义了以下类型:

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

与泛型类型及其泛型类型参数的信息没有关系。

如果你想访问Request对象,你应该把它添加到一个公共接口,例如IResponse,然后你的抽象泛型类型实现:

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

这至少允许您访问请求对象—尽管您可能仍然需要强制转换它。

尝试:

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;
}

注意,即使Request继承了IRequestFromResponse, BaseRequestWrapperResponse也不会继承BaseRequestWrapperResponse,因此你不能这样做:

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

如果模型的泛型实际上是BaseRequestWrapperResponse

相关内容

  • 没有找到相关文章

最新更新