繁体   English   中英

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

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

我有以下类的构造:

public class Request : BaseRequest, IRequestFromResponse
{
}

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

ModelRequest如下:

public class Response : BaseRequestWrapperResponse<Request>
{
}

构建BaseWrapper时:

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

IRequestFromResponse只是一个空的marker-interface。

我尝试在运行时BaseRequestWrapperResponse对象,因此我可以访问BaseRequestWrapperResponseRequest -property。

到目前为止我只有:

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>

只要将type参数放入其中,就必须了解泛型类型是具体类型 。因此,由于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;
    }

如果model的泛型实际上是BaseRequestWrapperResponse

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM