Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
144 views
in Technique[技术] by (71.8m points)

c# covariant generic parameter

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...