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

How to check if object inherits from a generic base class without knowing type of typeparam

我对 类 有以下构造:

public class Request : BaseRequest, IRequestFromResponse
{
}

它定义了一个 Request 对象,通过 html 表单发布。

ModelRequest 生活在这样的地方:

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 的支票。演员表将是我的下一个问题。

这不起作用,因为该模型的唯一类型是 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

添加一个非泛型如何 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; }
    }
}

然后:

model = ((BaseRequestWrapperResponse) model).Request;