Generic Variance in C# 4.0

前端 未结 3 1212
孤城傲影
孤城傲影 2020-12-08 11:20

Generic Variance in C# 4.0 has been implemented in such a way that it\'s possible to write the following without an exception (which is what would happen in C# 3.0):

3条回答
  •  长情又很酷
    2020-12-08 12:00

    No, your example wouldn't work for three reasons:

    • Classes (such as List) are invariant; only delegates and interfaces are variant
    • For variance to work, the interface has to only use the type parameter in one direction (in for contravariance, out for covariance)
    • Value types aren't supported as type arguments for variance - so there's no converstion from IEnumerable to IEnumerable for example

      (The code fails to compile in both C# 3.0 and 4.0 - there's no exception.)

      So this would work:

      IEnumerable strings = new List();
      IEnumerable objects = strings;
      
      
      

      The CLR just uses the reference, unchanged - no new objects are created. So if you called objects.GetType() you'd still get List.

      I believe it wasn't introduced earlier because the language designers still had to work out the details of how to expose it - it's been in the CLR since v2.

      The benefits are the same as other times where you want to be able to use one type as another. To use the same example I used last Saturday, if you've got something implements IComparer to compare shapes by area, it's crazy that you can't use that to sort a List - if it can compare any two shapes, it can certainly compare any two circles. As of C# 4, there'd be a contravariant conversion from IComparer to IComparer so you could call circles.Sort(areaComparer).

      提交回复
      热议问题