C# 协方差结构理解吗?
假设
A级 { }
B 级:A { }
泛型类不支持
协方差。意思是 - 我们不能做这样的事情:
MyConverter<B> x1= new MyConverter<B>();
MyConverter<A> x2= x1;
很好并且可以理解。
从我的阅读中,我了解到协方差将可用:
“如果您使用在通用类上实现的支持通用接口,则可以通过这些接口访问 T 类型对象实例”。
我只有一个问题。
我见过许多以 Stack
形式呈现“转换器”类的示例。
但从未理解“如果我只想使用 A 的引用中的 B 的 1 个实例怎么办?”
所以我尝试了一些代码:
创建
B
对象+值--->使用B
的通用转换器 ---> 使用协方差流来获取其A
引用 --->现在你可以使用它了 作为 A 或作为 B。
我的问题:
这是执行此操作的正确方法吗(仅对 1 个对象使用协方差)?
ps 代码工作正常并且编译正常。 https://i.sstatic.net/PJ6QO.png
我一直在问/读很多东西最近关于这个话题——我深入研究事物,以便尽可能地理解它们。
Assuming
class A
{ }class B : A
{ }
covariance is not supported for generic class.
Meaning - we cant do something like this :
MyConverter<B> x1= new MyConverter<B>();
MyConverter<A> x2= x1;
Thats fine and understood.
From my reading - i understand that Covariance will be available:
"If you use a backing Generic Interface Being implemented on a Generic Class - so that access to the T type object instance will be available through those interfaces ".
I have just one problem.
Ive seen many examples of the "converter" class as a form of Stack
.
But never understood " what if I want to use only 1 instance of B from a reference of A ? "
so Ive tried some code :
Create
B
object + values ---> use Generic Converter forB
--->
use the covariance flow to get itsA
reference ---> now you can use it
either as A or as B.
My question :
Is That the correct way of doing this ( for using covariance for 1 object only ) ?
p.s.
The code is working and compiled ok. https://i.sstatic.net/PJ6QO.png
Ive been asking /reading a lot about this topic lately - I dive into things in order to understand them the best I can.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的代码可以编译并运行,那么它“正确”吗?我想是的!
然而,拥有一个仅包含单个元素的堆栈并不是很有趣;这并不是真正的堆栈。让我们考虑一下如何创建一个真正的协变和逆变堆栈。
现在你可以协变地使用堆栈来弹出,并使用逆变来推入:
您的问题是“如果我想使用老虎但我有一个动物参考怎么办?”答案是“你不能”,因为该动物可能不是老虎!如果您想测试对 Animal 的引用是否真的是老虎,请说:
或
那是不可能的。那里没有参考转换。 C# 4 中唯一的协变和逆变引用转换是在使用引用类型作为类型参数构建的泛型接口和泛型委托上。类和结构不能协变或逆变使用。您能做的最好的事情就是让类实现一个变体接口。
Your code compiles and works, so is it "correct"? I guess it is!
However it is not very interesting having a stack that only contains a single element; that's not really a stack. Let's think about how you might make a truly covariant and contravariant stack.
And now you can use the stack covariantly for popping, and contravariantly for pushing:
Your question is "what if I want to use a Tiger but I have a reference an Animal?" The answer is "you can't" because the Animal might not be a Tiger! If you want to test whether the reference to Animal is really a tiger then say:
or
That's not possible. There is no reference conversion there. The only covariant and contravariant reference conversions in C# 4 are on generic interfaces and generic delegates that are constructed with reference types as the type arguments. Generic classes and structs may not be used covariantly or contravariantly. The best thing you can do is make the class implement a variant interface.
看起来您使用转换器只是为了获取指向
B
类型对象的A
类型引用。有一种更简单的方法可以做到这一点,称为强制转换:事实上,由于 A 是 B 的超类,因此转换是隐式的:
您的程序可以是:
It looks like you're using the converter simply to get a reference of type
A
pointing to an object of typeB
. There's a much easier way to do that, called casting:In fact, since A is a superclass of B, the conversion is implicit:
Your program could be:
您可以在 此博客。
You can find some great examples and descriptions of it on this blog.