簡體   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