将委托方法与委托签名匹配时,协变和逆变提供了一定程度的灵活性。协变允许将带有派生返回类型的方法用作委托,逆变允许将带有派生参数的方法用作委托。这使委托方法的创建变得更为灵活,并能够处理多个特定的类或事件。
协变
当委托方法的返回类型具有的派生程度比委托签名更大时,就称为协变委托方法。因为方法的返回类型比委托签名的返回类型更具体,所以可对其进行隐式转换。这样该方法就可用作委托。
协变使得创建可被类和派生类同时使用的委托方法成为可能。
示例 1
说明
此示例演示委托如何使用派生的返回类型。SecondHandler 返回的数据类型为 Dogs 类型,是委托签名返回类型 Mammals 的子集。因此,SecondHandler 返回的所有可能值都可以存储在 Mammals 类型的变量中。
代码
| C# | 复制代码 |
|---|---|
class Mammals
{
}
class Dogs : Mammals
{
}
class Program
{
// Define the delegate.
public delegate Mammals HandlerMethod();
public static Mammals FirstHandler()
{
return null;
}
public static Dogs SecondHandler()
{
return null;
}
static void Main()
{
HandlerMethod handler1 = FirstHandler;
// Covariance allows this delegate.
HandlerMethod handler2 = SecondHandler;
}
}
| |
逆变
当委托方法签名具有一个或多个参数,并且这些参数的类型派生自方法参数的类型时,就称为逆变委托方法。因为委托方法签名参数比方法参数更具体,因此可以在传递给处理程序方法时对它们进行隐式转换。
这样逆变使得可由大量类使用的更通用的委托方法的创建变得更加简单。
示例 2
说明
此示例演示委托如何使用从委托签名参数类型派生的类型的参数。因为要求委托支持 Dogs 类型的参数,我们知道带有 Mammals 类型的参数的处理程序一定是可接受的,因为 Dogs 是 Mammals 的子集。
代码
| C# | 复制代码 |
|---|---|
class Mammals
{
}
class Dogs : Mammals
{
}
class Program
{
public delegate void HandlerMethod(Dogs sampleDog);
public static void FirstHandler(Mammals elephant)
{
}
public static void SecondHandler(Dogs sheepDog)
{
}
static void Main(string[] args)
{
// Contravariance permits this delegate.
HandlerMethod handler1 = FirstHandler;
HandlerMethod handler2 = SecondHandler;
}
}
| |
请参见