C#的协变泛型参数 [英] c# covariant generic parameter

查看:159
本文介绍了C#的协变泛型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想明白这一点,但我没有从搜索得到任何相应的结果。



在C#4,我可以做

 公共接口IFoo的<出T> 
{

}



是如何从这种不同的

 公共接口IFoo的< T> 
{

}



我所知道的是退出使得泛型参数协(??)。
谁能解释<的使用;从T> 用一个例子的一部分?而也就是为什么只适用于接口和委托,不上课?



很抱歉,如果这是一个重复,并关闭它是这样,如果它是。


解决方案

有人能解释出牛逼的部分用一个例子使用?




当然。 的IEnumerable< T> 是协变的。这意味着你可以这样做:

 静态无效FeedAll(IEnumerable的<动物>动物)
{
的foreach(动物兽兽)animal.Feed();
}

...

IEnumerable的<&长颈鹿GT;长颈鹿= GetABunchOfGiraffes();
FeedAll(长颈鹿);



共变指的的类型参数的赋值相容性关系是在通用保留键入的。 长颈鹿分配兼容动物,因此,这种关系在构造类型保留: IEnumerable的<长颈鹿> 是分配兼容的IEnumerable<动物方式>




为什么只对接口和委托而不是类适用?




使用类的问题是,班往往具有可变领域。让我们举一个例子。假设我们允许这样的:

 类℃下进行T> 
{
私人T(T);



好了,现在想通过你去之前,请仔细这个问题。 能否 C< T> 有什么方法,设置字段 T 以外的东西构造之外?它的默认



由于它必须是类型安全, C< T> 现在有没有方法即采取T作为一个参数; T能够只返回。那么,谁套t和的他们在哪里得到他们将它从值的?



协变类的类型真的只是如果类是工作一成不变的。我们没有一个很好的方法,使在C#中一成不变的类。



我希望我们做到了,但我们要住在一起,我们给予CLR类型系统。我希望在未来我们可以有两种一成不变的类更好的支持,以及协变类。



如果该功能你感兴趣,可以阅读我的长期系列上,我们如何设计并实现了该功能。从底部开始:



https://blogs.msdn.microsoft.com/ericlippert/tag/covariance-and-contravariance/


I'm trying to understand this but I didn't get any appropriate results from searching.

In c# 4, I can do

    public interface IFoo<out T>
    {

    }

How is this different from

    public interface IFoo<T>
    {

    }

All I know is the out makes the generic parameter covariant (??). Can someone explain the usage of <out T> part with an example? And also why is applicable only for interfaces and delegates and not for classes?

Sorry if it's a duplicate and close it as such if it is.

解决方案

Can someone explain the usage of the out T part with an example?

Sure. IEnumerable<T> is covariant. That means you can do this:

static void FeedAll(IEnumerable<Animal> animals) 
{
    foreach(Animal animal in animals) animal.Feed();
}

...

 IEnumerable<Giraffe> giraffes = GetABunchOfGiraffes();
 FeedAll(giraffes);

"Covariant" means that the assignment compatibility relationship of the type argument is preserved in the generic type. Giraffe is assignment compatible with Animal, and therefore that relationship is preserved in the constructed types: IEnumerable<Giraffe> is assignment compatible with IEnumerable<Animal>.

Why is applicable only for interfaces and delegates and not for classes?

The problem with classes is that classes tend to have mutable fields. Let's take an example. Suppose we allowed this:

class C<out T>
{
    private T t;

OK, now think this question through carefully before you go on. Can C<T> have any method outside of the constructor that sets the field t to something other than its default?

Because it must be typesafe, C<T> can now have no methods that take a T as an argument; T can only be returned. So who sets t, and where do they get the value they set it from?

Covariant class types really only work if the class is immutable. And we don't have a good way to make immutable classes in C#.

I wish we did, but we have to live with the CLR type system that we were given. I hope in the future we can have better support for both immutable classes, and for covariant classes.

If this feature interests you, consider reading my long series on how we designed and implemented the feature. Start from the bottom:

https://blogs.msdn.microsoft.com/ericlippert/tag/covariance-and-contravariance/

这篇关于C#的协变泛型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆