簡體   English   中英

嘗試在擴展類型T上實現抽象泛型類時出現C#編譯錯誤

[英]C# Compilation Error When Trying To Implement An Abstract Generic Class On An Extended Type T

我正在使用泛型,覺得自己已經陷入了沉思,想知道StackOverflow是否可以提供幫助? 我認為使用我的代碼的簡化版本來解釋我的問題要容易得多,而不是使用類A擴展類B的抽象示例等。我對此表示歉意,盡管它過於簡單。

我的C#(Windows Phone 7 .NET 3.5 )應用程序將請求激發到Web服務,並使用XML響應填充從基類WebServiceResult派生的Result對象。 最初,它觸發了請求,解析了響應,然后調用方法將把Result類型轉換為預期的結果。 我以為,既然我們知道我們期望的結果類型,那么這是沒有意義的,因此嘗試使用泛型來解決這個問題。

// abstract class to do the raw http response handling
public abstract class WebServiceResultParser<T> where T : WebServiceResult {
    T result;
    public WebServiceResultParser(T result) {
        this.result = result;
    }

    protected abstract bool Parse(String response);
    private bool ParseHttpResponse(HttpWebResponse httpWebResponse){
        //some logic to get http response as string
        result.GetParser<T>().Parse(http_response_as_string);
        return true;
    }
}

// abstract class that models a webservice result
public abstract class WebServiceResult {
   protected internal abstract WebServiceResultParser<T> GetParser<T>() 
                                                where T : WebServiceResult;
}

實現“注冊” Web服務請求

// knows how to parse the xml
public class RegistrationResultParser : WebServiceResultParser<RegistrationResult>{
    private RegistrationResult result;
    public RegistrationResultParser(RegistrationResult result)
        : base(result) {
            this.result = result;
    }

    protected override bool Parse(String response){
        //some logic to extract customer number
        result.CustomerNumber = customerNumber;
        return true;
    }
}
// stores the result
public class RegistrationResult : WebServiceResult {
    public String CustomerNumber { get; internal set; }

    protected internal override WebServiceResultParser<T> GetParser<T>() {
        return new RegistrationResultParser(this); // <--- Compiler error here
    }
}

編譯器錯誤說

無法將類型'RegistrationResultParser'隱式轉換為' WebServiceResultParser<T> '

這是我所能進行的,而又不會繞圈走。 任何建議,進一步的閱讀或評論,將不勝感激。

干杯,阿拉斯台爾。

編寫代碼的方式無法保證GetParser<T>會返回WebServiceResultParser<RegistrationResult> (這是RegistrationResultParser繼承的),因此無法進行編譯。

我認為,如果將方法更改為:

protected internal override WebServiceResultParser<RegistrionResult> 
    GetParser<RegistrationResult>()
{
    return new RegistrationResultParser(this);
}

目前的類結構無法編譯,因為.NET框架在泛型上不是協變或相反的(嗯,它不是.NET 4.0之前的版本)。 可以在此處找到有關泛型的協方差和協方差(包括如何在.NET 4.0中指定它們)的很好的文章: http : //msdn.microsoft.com/zh-cn/library/dd799517.aspx

不過,這有點使問題蒙上了陰影,因為我不認為向您的類層次結構添加差異支持才是答案。

如果我正確理解了您的意圖-在RegistrationResult您試圖說要GetParser()方法返回WebResultParser<RegistrationResult> (而不是其他任何WebServiceResult類型的WebResultParser )。

要使其工作,您需要進行以下更改(注釋中的注釋):

// update the constraint to match the new WebServiceResult definition
public abstract class WebServiceResultParser<T> where T : WebServiceResult<T>
{
    T result;
    public WebServiceResultParser(T result)
    {
        this.result = result;
    }

    protected abstract bool Parse(String response);
    private bool ParseHttpResponse(HttpWebResponse httpWebResponse)
    {
        //some logic to get http response as string
        var http_response_as_string = httpWebResponse.ToString();
        result.GetParser().Parse(http_response_as_string);
        return true;
    }
}

// move the type constraint from the GetParser() method to the class itself
public abstract class WebServiceResult<T> where T : WebServiceResult<T>
{
    protected internal abstract WebServiceResultParser<T> GetParser();
}

// no change
public class RegistrationResultParser : WebServiceResultParser<RegistrationResult>
{
    private RegistrationResult result;
    public RegistrationResultParser(RegistrationResult result)
        : base(result)
    {
        this.result = result;
    }

    protected override bool Parse(String response)
    {
        //some logic to extract customer number
        //result.CustomerNumber = customerNumber;
        return true;
    }
}

// explicitly specify the constraint on the base class (which is used to
// specify the GetParser() return type)
public class RegistrationResult : WebServiceResult<RegistrationResult>
{
    public String CustomerNumber { get; internal set; }

    protected internal override WebServiceResultParser<RegistrationResult> GetParser()
    {
        return new RegistrationResultParser(this);
    }
}

這是因為由於才打破RegistrationResultParser從繼承WebServiceResultParser<RegistrationResult> ,而不是從WebServiceResultParser<T>

整個A : B<A>看起來確實有些奇怪,但是它確實實現了您要嘗試執行的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM