试图在扩展类型T上实现抽象泛型类时出现C#编译错误
我正在使用泛型,我觉得我已经陷入了太深的头脑中,想知道StackOverflow是否能帮上忙?我认为用我的代码的简化版本来解释我的问题要容易得多,而不是用一个抽象的类a扩展类B等等的例子。如果过于简单,我很抱歉 我的C#(Windows Phone 7.NET 3.5)应用程序向Web服务发出请求,并使用填充从基类WebServiceResult派生的结果对象的XML响应。最初它启动请求,解析响应,然后调用方法将结果类型转换为它期望的结果。我认为,既然我们知道我们期望的结果是什么类型的,这是毫无意义的,并试图使用泛型来克服这一点试图在扩展类型T上实现抽象泛型类时出现C#编译错误,c#,generics,.net-3.5,C#,Generics,.net 3.5,我正在使用泛型,我觉得我已经陷入了太深的头脑中,想知道StackOverflow是否能帮上忙?我认为用我的代码的简化版本来解释我的问题要容易得多,而不是用一个抽象的类a扩展类B等等的例子。如果过于简单,我很抱歉 我的C#(Windows Phone 7.NET 3.5)应用程序向Web服务发出请求,并使用填充从基类WebServiceResult派生的结果对象的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;
}
//执行原始http响应处理的抽象类
公共抽象类WebServiceResultParser,其中T:WebServiceResult{
T结果;
公共WebServiceResultParser(T结果){
this.result=结果;
}
受保护的抽象布尔解析(字符串响应);
私有布尔解析HttpResponse(HttpWebResponse HttpWebResponse){
//将http响应作为字符串获取的一些逻辑
result.GetParser().Parse(http_响应作为_字符串);
返回true;
}
}
//为webservice结果建模的抽象类
公共抽象类WebServiceResult{
受保护的内部抽象WebServiceResultParser GetParser()
其中T:webservicesult;
}
“注册”webservice请求的实现
// 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
}
}
//知道如何解析xml
公共类注册结果解析器:WebServiceResultParser{
私人注册结果;
公共注册结果服务器(注册结果)
:基准(结果){
this.result=结果;
}
受保护的覆盖布尔解析(字符串响应){
//提取客户号的一些逻辑
result.CustomerNumber=CustomerNumber;
返回true;
}
}
//存储结果
公共类注册结果:WebServiceResult{
公共字符串CustomerNumber{get;internal set;}
受保护的内部重写WebServiceResultParser GetParser(){
返回新的RegistrationResultParser(this);//按照编写代码的方式,GetParser
无法保证将返回WebServiceResultParser
(这是RegistrationResultParser继承的内容),因此无法编译
我认为如果您将方法更改为:
protected internal override WebServiceResultParser<RegistrionResult>
GetParser<RegistrationResult>()
{
return new RegistrationResultParser(this);
}
受保护的内部重写WebServiceResultParser
GetParser()
{
返回新的RegistrationResultPasser(此);
}
当前的类结构无法编译,因为.NET framework在泛型上不是协变或逆变的(好吧,它不是.NET 4.0之前的版本)。在这里可以找到一篇关于泛型的协变和逆变的好文章(包括如何在.NET 4.0中指定它们):
不过,这有点模糊了这个问题,因为我不认为向类层次结构添加差异支持是答案
如果我正确理解了您的意图-在RegistrationResult
中,您试图说希望GetParser()
方法返回WebResultParser
(而不是任何其他类型的WebServiceResult
)的WebResultParser
)
要使其像这样工作,您需要进行以下更改(注释中的注释):
//更新约束以匹配新的WebServiceResult定义
公共抽象类WebServiceResultParser,其中T:WebServiceResult
{
T结果;
公共WebServiceResultParser(T结果)
{
this.result=结果;
}
受保护的抽象布尔解析(字符串响应);
私有布尔解析HttpResponse(HttpWebResponse HttpWebResponse)
{
//将http响应作为字符串获取的一些逻辑
var http_response_as_string=httpWebResponse.ToString();
result.GetParser().Parse(http_响应作为_字符串);
返回true;
}
}
//将类型约束从GetParser()方法移动到类本身
公共抽象类WebServiceResult,其中T:WebServiceResult
{
受保护的内部抽象WebServiceResultParser GetParser();
}
//不变
公共类注册结果解析器:WebServiceResultParser
{
私人注册结果;
公共注册结果服务器(注册结果)
:基准(结果)
{
this.result=结果;
}
受保护的覆盖布尔解析(字符串响应)
{
//提取客户号的一些逻辑
//result.CustomerNumber=CustomerNumber;
返回true;
}
}
//显式指定基类上的约束(用于
//指定GetParser()返回类型)
公共类注册结果:WebServiceResult
{
公共字符串CustomerNumber{get;internal set;}
受保护的内部重写WebServiceResultParser GetParser()
{
返回新的RegistrationResultPasser(此);
}
}
它以前是中断的,因为RegistrationResultParser
仅从WebServiceResultParser
继承,而不是从WebServiceResultParser
整个A:B
看起来确实有点奇怪,但它确实实现了您想要做的事情。如果我做了此更改,编译器会抱怨我没有正确实现抽象类。'RegistrationResult'没有实现继承的抽象成员'WebServiceResult.GetDefaultParser()“刚刚看到您的编辑,它与@Rohit相同,但不能像编译器所说的那样工作。无法将类型“RegistrationResultParser”隐式转换为“WebServiceResultParserThank you”,这是泛型的一个惊人用法。我需要坐下来充分理解它的作用
// 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);
}
}