尝试在扩展类型 T 上实现抽象泛型类时出现 C# 编译错误

标签 c# generics .net-3.5

我正在使用泛型,但感觉自己已经陷得太深了,想知道 StackOverflow 是否可以提供帮助?我认为使用代码的简化版本来解释我的问题会容易得多,而不是使用 A 类扩展 B 类的抽象示例等。如果它过于简单,我深表歉意。

我的 C# (Windows Phone 7 .NET 3.5) 应用程序向 Web 服务发出请求,并使用填充从基类 WebServiceResult 派生的 Result 对象的 XML 响应。最初它触发请求,解析响应,然后调用方法将 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;
}

实现“注册”网络服务请求

// 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
    }
}

编译器错误提示

Cannot implicitly convert type 'RegistrationResultParser' to 'WebServiceResultParser<T>'

这就是我在不兜圈子的情况下能走的最远的地方了。任何建议、进一步阅读或评论将不胜感激。

干杯, 阿拉斯代尔。

最佳答案

现有的类结构无法编译,因为 .NET 框架在泛型上不是协变或逆变的(嗯,它不是 .NET 4.0 之前的版本)。可以在这里找到一篇关于泛型协变和逆变(包括如何在 .NET 4.0 中指定它们)的好文章:http://msdn.microsoft.com/en-us/library/dd799517.aspx

但这有点掩盖了问题,因为我不认为向类层次结构添加方差支持就是答案。

如果我正确理解你的意图 - 在 RegistrationResult你想说你想要 GetParser()方法返回 WebResultParser<RegistrationResult> (与 WebResultParser 相对于任何其他类型的 WebServiceResult )。

要使其像这样工作,您需要进行以下更改(注释中的注释):

// 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>看起来确实有点奇怪,但它确实实现了您想要做的事情。

关于尝试在扩展类型 T 上实现抽象泛型类时出现 C# 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5435808/

相关文章:

c# - 序列化对象 - 替换值

c# - 加载异步 WP8.1 : Partial result

c# - StreamWriter构造函数中的参数无效?

java - addAll(Collection).. 不适用于参数(Iterable)

c# - 使用 .NET 4.0 编译器编译 .NET 3.5 项目

.net - 将 PowerShell 与 .NET 3.5 运行时/库一起使用

c# - 如何在 C# 中解码 URL 转义字符串?

javascript - 无法读取未定义(…)的属性 '_aData' - 数据表

java通用通配符 "?"

c# - 如何在 C# 中正确处理相关但不同类的调用方法