作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 CoVariance 和 ContraVariance 有点怀疑..请参阅以下代码..
interface IGetElement<out T>
{
int Counter { get; }
T GetNext();
}
interface IAddElement<in T>
{
void Add(T t);
}
class Collection<T> : IAddElement<T>, IGetElement<T> where T : Fruit
{
List<T> tList = new List<T>();
private int _counter = 0;
public int Count { get { return tList.Count; } }
public void Add(T t)
{
tList.Add(t);
}
int IGetElement<T>.Counter
{
get { return _counter; }
}
public T GetNext()
{
return tList[_counter++];
}
public void Rset()
{
_counter = 0;
}
}
abstract class Fruit
{
public abstract void Taste();
}
class Apple : Fruit
{
public override void Taste()
{
Console.WriteLine("Like Apple");
}
}
这是示例代码..现在客户端是
static void Main(string[] args)
{
IGetElement<Fruit> covarience = new Collection<Apple>(); // CoVarience..
IAddElement<Apple> contravarience = new Collection<Fruit>();//ContraVarience.. Compiling fine and working also fine... :)
IGetElement<Fruit> fruits = new Collection<Apple>();
IAddElement<Fruit> apples2 = fruits as IAddElement<Apple>;//Here its Compiler error : Cannot implicitly convert type 'Test.IAddElement<Test.Apple>' to 'Test.IAddElement<Test.Fruit>'. An explicit conversion exists (are you missing a cast?)
IAddElement<Apple> apples1 = fruits as IAddElement<Fruit>;//This is not posible
/* Why this is not possible..? In this case No Compiler Error But Run Time error ie.,
apples1 is NULL.. I don't know why.. because.. in fruits cantains apple only but
It is unable it caste it as ContrVariantly.. ?------------1 */
IAddElement<Apple> apples = fruits as IAddElement<Apple>;//This is posible
IGetElement<Fruit> f = apples as IGetElement<Apple>;//This is posible..
/* Why this is posible.. ? here we are casting t as CoVariantly..
If ------------1 is not posible how this would be posible... yes.. I am casting to
actual object which is not Null.. ? -----------2 */
}
请在注释源代码中回答我的问题...:) ------1,--------2。
感谢和问候,迪内什
最佳答案
进一步扩展 James 的回答:
- Why this is not possible? In this case there is no compiler error but at runtime apples1 is null. I don't know why.
运行时的局部变量 fruits 指的是类型为 Collection<Apple>
的对象.也就是说,一个仅包含苹果的集合。
您在问“我可以向这个系列中添加任何水果吗?”不可以。您只能添加苹果,不能添加任何水果。因此结果为空。
这在运行时而不是在编译时失败的原因是因为 fruit 的编译时类型是一种接口(interface)类型,而您正在将其转换为不同的接口(interface)类型。任何两个接口(interface)都可能由给定的对象实现;编译器不会进行流分析来确定 fruits 只被分配了一种特定类型。因此检查要到运行时才能完成。
- Why this is posible? Here we are converting covariantly.
这里有两个转换。第一个苹果被转换为IGetElement<Apple>
然后将其协变转换为 IGetElement<Fruit>
.
第一次转换成功,因为局部变量 apples 引用了一个 Collection<Apple>
实现IGetElement<Apple>
.你在问“这个物体能给我一个苹果吗?”答案是肯定的。
第二次转换成功,因为编译器知道“一个可以给我一个苹果的对象”可以安全地被视为“一个可以给我一个水果的对象”。
现在清楚了吗?
关于c# - 协方差 反方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7432447/
我是一名优秀的程序员,十分优秀!