如何在不知道类型参数类型的情况下检查对象是否继承自泛型基 class
How to check if object inherits from a generic base class without knowing type of typeparam
我对 类 有以下构造:
public class Request : BaseRequest, IRequestFromResponse
{
}
它定义了一个 Request
对象,通过 html 表单发布。
Model
,Request
生活在这样的地方:
public class Response : BaseRequestWrapperResponse<Request>
{
}
构建 BaseWrapper 时:
public abstract class BaseRequestWrapperResponse<TRequest> where TRequest : IRequestFromResponse
{
public TRequest Request { get; set; }
}
IRequestFromResponse
只是一个空的标记界面。
我尝试在运行时转换对象,所以我可以访问 BaseRequestWrapperResponse
的 Request
-属性。
目前我只有:
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
的支票。演员表将是我的下一个问题。
这不起作用,因为该模型的唯一类型是 Response
和 BaseRequestWrapperResponse<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;
我对 类 有以下构造:
public class Request : BaseRequest, IRequestFromResponse
{
}
它定义了一个 Request
对象,通过 html 表单发布。
Model
,Request
生活在这样的地方:
public class Response : BaseRequestWrapperResponse<Request>
{
}
构建 BaseWrapper 时:
public abstract class BaseRequestWrapperResponse<TRequest> where TRequest : IRequestFromResponse
{
public TRequest Request { get; set; }
}
IRequestFromResponse
只是一个空的标记界面。
我尝试在运行时转换对象,所以我可以访问 BaseRequestWrapperResponse
的 Request
-属性。
目前我只有:
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
的支票。演员表将是我的下一个问题。
这不起作用,因为该模型的唯一类型是 Response
和 BaseRequestWrapperResponse<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;