委托的匿名方法,以及在协变与逆变中的应用
2008-08-27 08:43
288 查看
委托的匿名方法
这几天在看微软的MVP设计模式的例子的时候,偶然发现它将DropDownList的SelectIndexChange事件委托直接实例化成一个不带任何参数匿名方法。
如下:
this.customerDropDownList.SelectedIndexChanged += delegate
{
presenter.DisplayCustomerDetails();
};
这让我不禁起了疑惑。SelectedIndexChanged事件委托应该要带有一个参数EventArgs才对啊。为什么它用这函数实例化呢?
几经查询,终于明白了,不带括弧delegate 关键字将定义一种特殊的匿名方法,它可以指派给具有任何签名的任何委托。就如上面的代码一样。如果使用匿名方法,则不必创建单独的方法,因此减少了实例化委托所需的编码系统开销。
委托的协变与逆变
协变允许方法具有的派生返回类型比委托中定义的更多。而委托还有一种逆变,逆变允许方法具有的派生参数类型比委托类型中的更少。将方法签名与委托类型匹配时,协变和逆变提供了一定程度的灵活性。
下面分别提供一个简单的例子说明一下。
1.协变。
以下委托将定义为具有Human返回类型的委托,而实例化委托的方法中有一个返回类型是Women类型的。Women类型是由Human类型派生的。
class Human
{
public override string ToString()
{
return "human";
}
}
class Women: Humen
{
public override string ToString()
{
return "women";
}
}
class Program
{
/// <summary>
/// 定义一个返回类型为Human的委托。
/// </summary>
/// <returns>返回一个Human对象。</returns>
public delegate Human GetHumanHandler();
public static Human GetHuman()
{
Human human;
if (isWomen)
{
human = new Women();
Console.WriteLine(human);
return human;
}
human = new Human();
Console.WriteLine(human);
return human;
}
public static Human GetWomen()
{
Women human = new Women();
Console.WriteLine(human);
return human;
}
static void Main(string[] args)
{
//命名方法
GetHumanHandler handler1 = GetHuman;
//匿名方法
GetHumanHandler handler2 = delegate{
return GetWomen(); };
handler1.Invoke(false);
handler2.Invoke(true);
}
}
2.逆变
以下委托将定义为一个带有Human类型参数的委托何一个带有Women类型参数的委托。Women类型是由Human类型派生的。
而实例化委托的方法中只是一个带有Human类型参数的方法。两个委托共用一个方法实例。
class Human
{
}
class Women : Human
{
}
class Program
{
public delegate void HumanInfoPrintHandler(Human human);
public delegate void WomenInfoPrintHandler(Women human);
public static void HumanInfoPrint(Human human)
{
if (human is Women)
{
Console.WriteLine("women");
}
else
{
Console.WriteLine("human");
}
}
static void Main(string[] args)
{
HumanInfoPrintHandler handler1 = HumanInfoPrint;
WomenInfoPrintHandler handler2 = HumanInfoPrint;
handler1.Invoke(new Human());
handler2.Invoke(new Women());
}
}
MSDN官方资料请参看(C#编程指南)
http://msdn.microsoft.com/zh-cn/library/ms173174(VS.80).aspx
这几天在看微软的MVP设计模式的例子的时候,偶然发现它将DropDownList的SelectIndexChange事件委托直接实例化成一个不带任何参数匿名方法。
如下:
this.customerDropDownList.SelectedIndexChanged += delegate
{
presenter.DisplayCustomerDetails();
};
这让我不禁起了疑惑。SelectedIndexChanged事件委托应该要带有一个参数EventArgs才对啊。为什么它用这函数实例化呢?
几经查询,终于明白了,不带括弧delegate 关键字将定义一种特殊的匿名方法,它可以指派给具有任何签名的任何委托。就如上面的代码一样。如果使用匿名方法,则不必创建单独的方法,因此减少了实例化委托所需的编码系统开销。
委托的协变与逆变
协变允许方法具有的派生返回类型比委托中定义的更多。而委托还有一种逆变,逆变允许方法具有的派生参数类型比委托类型中的更少。将方法签名与委托类型匹配时,协变和逆变提供了一定程度的灵活性。
下面分别提供一个简单的例子说明一下。
1.协变。
以下委托将定义为具有Human返回类型的委托,而实例化委托的方法中有一个返回类型是Women类型的。Women类型是由Human类型派生的。
class Human
{
public override string ToString()
{
return "human";
}
}
class Women: Humen
{
public override string ToString()
{
return "women";
}
}
class Program
{
/// <summary>
/// 定义一个返回类型为Human的委托。
/// </summary>
/// <returns>返回一个Human对象。</returns>
public delegate Human GetHumanHandler();
public static Human GetHuman()
{
Human human;
if (isWomen)
{
human = new Women();
Console.WriteLine(human);
return human;
}
human = new Human();
Console.WriteLine(human);
return human;
}
public static Human GetWomen()
{
Women human = new Women();
Console.WriteLine(human);
return human;
}
static void Main(string[] args)
{
//命名方法
GetHumanHandler handler1 = GetHuman;
//匿名方法
GetHumanHandler handler2 = delegate{
return GetWomen(); };
handler1.Invoke(false);
handler2.Invoke(true);
}
}
2.逆变
以下委托将定义为一个带有Human类型参数的委托何一个带有Women类型参数的委托。Women类型是由Human类型派生的。
而实例化委托的方法中只是一个带有Human类型参数的方法。两个委托共用一个方法实例。
class Human
{
}
class Women : Human
{
}
class Program
{
public delegate void HumanInfoPrintHandler(Human human);
public delegate void WomenInfoPrintHandler(Women human);
public static void HumanInfoPrint(Human human)
{
if (human is Women)
{
Console.WriteLine("women");
}
else
{
Console.WriteLine("human");
}
}
static void Main(string[] args)
{
HumanInfoPrintHandler handler1 = HumanInfoPrint;
WomenInfoPrintHandler handler2 = HumanInfoPrint;
handler1.Invoke(new Human());
handler2.Invoke(new Women());
}
}
MSDN官方资料请参看(C#编程指南)
http://msdn.microsoft.com/zh-cn/library/ms173174(VS.80).aspx
相关文章推荐
- C#中委托的匿名方法,及其在协变与逆变中的应用
- c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对
- C#中分别对委托、匿名方法、Lambda表达式、Lambda表达式树以及反射执行同一方法的过程进行比较。
- 委托的由来以及委托链和委托的匿名方法
- 第五节:泛型(泛型类、接口、方法、委托、泛型约束、泛型缓存、逆变和协变)
- 匿名方法在委托实例化中的应用
- .NET Framework System.Array.Sort 数组类,加深对 IComparer、IComparable 以及泛型委托、匿名方法、Lambda 表达式的理解
- 委托的协变与逆变的应用
- c# 中的委托以及匿名方法lambda
- 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型
- C#中的委托,匿名方法和Lambda表达式
- 关于委托:异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }
- 最简单的匿名方法与委托示例
- 匿名方法、委托和Lambda表达式区分演示(图文解释)
- 温故而知新:Delegate,Action,Func,匿名方法,匿名委托,事件
- 委托匿名方法(C# 编程指南)
- vs2010——泛型委托的协变、逆变
- 委托、匿名方法、Lambda表达式的演进
- 命名的方法 匿名方法 对委托进行实例化
- 委托中的协变和逆变