我正在使用泛型,觉得我已经深入了解并且想知道StackOverflow是否可以提供帮助?我认为使用我的代码的简化版本来解释我的问题要容易得多,而不是A类扩展B类的抽象例子。如果它过于简单,我会道歉。
我的C#(Windows Phone 7 .NET 3.5 )应用程序向Web服务发出请求,并使用填充从基类WebServiceResult派生的Result对象的XML响应。最初它触发了请求,解析了响应,然后调用方法将类型转换为预期的结果。我认为既然我们知道我们期待什么类型的结果,这是毫无意义的,并尝试使用泛型来实现这一目标。
// 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
}
}
编译错误说
无法将“RegistrationResultParser”类型隐式转换为“
WebServiceResultParser<T>
”
这是我可以走的尽可能不绕圈而行。任何建议,进一步阅读或评论将不胜感激。
干杯, 麦金太尔。
答案 0 :(得分:3)
编写代码的方式,无法保证GetParser<T>
将返回WebServiceResultParser<RegistrationResult>
(这是RegistrationResultParser继承的内容),因此无法编译。
我认为如果将方法更改为:
,它应该可以正常工作protected internal override WebServiceResultParser<RegistrionResult>
GetParser<RegistrationResult>()
{
return new RegistrationResultParser(this);
}
答案 1 :(得分:3)
现在的类结构不能编译,因为.NET框架在泛型上不是协变的或逆变的(好吧,它不是.NET 4.0之前的版本)。有关协方差和与泛型相关的逆转(包括如何在.NET 4.0中指定它们)的好文章可以在这里找到:http://msdn.microsoft.com/en-us/library/dd799517.aspx
但这有点让问题蒙上阴影,因为我不认为为你的类层次结构添加方差支持就是答案。
如果我正确理解您的意图 - 在RegistrationResult
中,您试图说明您希望GetParser()
方法返回WebResultParser<RegistrationResult>
(而不是WebResultParser
1}}用于任何其他类型的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>
确实看起来有点奇怪,但它确实实现了你想要做的事情。