Covariance and Contravariance in C#, Part Four: Real Delegate Variance

C#泛型委托协变和逆变
本文探讨了C#中泛型委托类型的协变和逆变特性,并提出了如何通过声明类型参数为协变或逆变来增强这一特性。通过具体的例子展示了这种变化如何使得某些原本非法的赋值操作变得合法。
 

In the last two posts I discussed the two kinds of variance that C# already has -- array covariance and member-group-to-delegate conversion covariance (on return types) and contravariance (on formal parameter types).

Today I want to generalize the latter kind of variance.

In C# 3.0 today, even though it is legal to assign a typeless member group for a function that returns a Giraffe to a variable of type Func<Animal>, it is not legal to assign a typed expression of type Func<Giraffe> to a Func<Animal>. Generic delegate types are always invariant in C# 3.0. That seems weak.

Suppose we had the ability to declare type parameters of generic delegate types as being covariant or contravariant. For the sake of brevity (and consistency with existing notation in the CLR specification) I will notate a covariant type parameter with a + and a contravariant type parameter with a -.

This is not a particularly compelling notation; I will discuss its deficiencies in a later post. But for now we'll stick with it.The way to remember what it means is that a plus means "this type argument is allowed to get bigger upon assignment", and similarly for minus.

Consider for example our standard function:

delegate R Func<A, R>(A a);

Since R appears only in the returns and A appears only in the formal parameter list, we can make R covariant and A contravariant(‡):

delegate R Func< -A, +R >(A a);

So again, you can think of this as "you can make A smaller or R bigger" (or, of course, both). For example:

Func<Animal, Giraffe> f1 = whatever;
Func<Mammal, Mammal> f2 = f1;

Normally in C# this assignment would be illegal because the delegates are parameterized by different types. But since we have made Func variant in both its type parameters, this assignment would become legal were we to add this kind of variance to a hypothetical future version of C#.

Does that make sense so far?

(‡) This rule of thumb is not always correct! Sometimes the input parameters need to be of a covariant type parameter. I shall discuss just such a situation next time, and I promise that it will hurt your brain.

 

转载于:https://www.cnblogs.com/i2001she1u/archive/2009/02/27/1399723.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值