Roy*_*mir 15 c# .net-4.0 covariance
假设
A级{}
B级:A {}
泛型类不支持协方差.
含义 - 我们不能做这样的事情:
MyConverter<B> x1= new MyConverter<B>();
MyConverter<A> x2= x1;
Run Code Online (Sandbox Code Playgroud)
多数民众赞成并理解.
从我的阅读 - 我明白Covariance将可用:
"如果你使用支持通用接口在通用类上实现 - 那么通过这些接口可以访问T类型对象实例".
我只有一个问题.
我见过许多"转换器"类的例子Stack.
但是从来没有理解"如果我只想从A的引用中使用一个B实例怎么办?"
所以我尝试了一些代码:
创建
B对象+值--->使用Generic Converter forB--->使用协方差流来获取它的A参考--->现在你可以将它用作A或B.


我的问题 :
这是正确的方法吗(仅对1个对象使用协方差)?
ps代码正常工作并编译好.http://i.stack.imgur.com/PJ6QO.png
我最近一直在询问/阅读很多关于这个话题的内容 - 我深入研究了一些事情,以便尽我所能地理解它们.
Eri*_*ert 16
你的代码编译和工作,它是"正确的"吗?我想是的!
但是,堆栈只包含一个元素并不是很有趣; 这不是真的堆栈.让我们考虑如何制作一个真正的协变和逆变堆栈.
interface IPush<in T> { void Push(T item); }
interface IPop<out T> { T Pop(); }
class Stack<T> : IPush<T>, IPop<T>
{
private class Link
{
public T Item { get; private set; }
public Link Next { get; private set; }
public Link(T item, Link next) { this.Item = item; this.Next = next; }
}
private Link head;
public Stack() { this.head = null; }
public void Push(T item)
{
this.head = new Link(item, this.head);
}
public T Pop()
{
if (this.head == null) throw new InvalidOperationException();
T value = this.head.Item;
this.head = this.head.Next;
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以使用堆栈协变弹出,并且反之则推动:
Stack<Mammal> mammals = new Stack<Mammal>();
IPop<Animal> animals = mammals;
IPush<Giraffe> giraffes = mammals;
IPush<Tiger> tigers = mammals;
giraffes.Push(new Giraffe());
tigers.Push(new Tiger());
System.Console.WriteLine(animals.Pop()); // Tiger
System.Console.WriteLine(animals.Pop()); // Giraffe
Run Code Online (Sandbox Code Playgroud)
如果我只想从A的引用中使用B的一个实例怎么办?
你的问题是"如果我想使用老虎但我有参考动物怎么办?" 答案是"你不能",因为动物可能不是老虎!如果你想测试对Animal的引用是否真的是老虎,那就说:
Tiger tiger = myAnimal as Tiger;
if (tiger != null) ...
Run Code Online (Sandbox Code Playgroud)
要么
if (myAnimal is Tiger) ...
Run Code Online (Sandbox Code Playgroud)
怎么样,如果你想要类转换
C<B>到C<A>?
那是不可能的.那里没有参考转换.C#4中唯一的协变和逆变引用转换是在通用接口和通用委托上,这些委托使用引用类型作为类型参数构造.通用类和结构可能不会被共同使用或相反使用.您可以做的最好的事情是让类实现变体接口.
| 归档时间: |
|
| 查看次数: |
681 次 |
| 最近记录: |