Rob*_*ert 6 c# inheritance abstract-class
一些代码来复制问题:
using System;
public abstract class Response { }
public abstract class Request<T> where T : Response { }
public class LoginResponse : Response { }
public class LoginRequest : Request<LoginResponse> { }
public class Program
{
static void Main(string[] args)
{
LoginRequest login = new LoginRequest();
/* Error: Cannot implicitly convert type 'LoginRequest' to 'Request' */
Request<Response> castTest = login;
/* No Error */
Request<LoginResponse> castTest2 = login;
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,LoginRequest类是一个Request <Response>,因为它继承自Request <T>,而LoginResponse继承自Response,所以任何人都可以告诉我为什么我得到编译器错误?
注意:我也试过一个明确的演员
您收到错误是因为Request<Response>并且Request<LoginResponse>不是协变的.
仅仅因为LoginResponse继承Response并不意味着Request<LoginResponse>可以像对待一样Request<Response>.阅读本文:
因为您的泛型参数是隐式不变的 - 两种类型,Request<LoginResponse>并且Request<Response>完全不同.C#4.0引入了委托类型和接口的差异,可以在这里为您提供解决方案:
public interface IResponse<out T> where T : Response {}
Run Code Online (Sandbox Code Playgroud)
这里我们将泛型类型声明T为Covariant.
Eric Lippert撰写了许多关于C#差异主题的好博客文章,我强烈建议阅读它们.
这是因为C#泛型类不是协变的.C#试图阻止你做以下事情:
Request<Response> castTest = login;
castTest.Response = someOtherKindOfResponse;
Run Code Online (Sandbox Code Playgroud)
使用列表可能更清楚这个例子.想象一下,如果以下工作:
var someStringList = new List<String>();
var someObjectList = ((List<Object>)someStringList; // This throws a compile exception, thankfully
someObjectList.Add(1); // If the above worked, then this would compile, but would throw a runtime exception
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1106 次 |
| 最近记录: |