今天开始学习C#!
由于我有C++程序基础,为了理解老大给的代码,直接从委托开始学习。
委托,顾名思义就是将代码委托出去--即让代码决定什么时候调用我们委托的代码(虽然还是我们设置),就原理而言,感觉和C++中的回调函数性质差不多。
在C#中,我们一般使用委托时先要在类外面声明(类和委托应该是等价的,都需要实例化,但是委托的实例化还是叫委托),例如,我们要编写一个冒泡排序:
delegate bool ComparisonHandler(int first, int second);//委托的声明
class DelegateSample
{
public static void BubbleSort(
int[] items,ComparisonHandler comparisonMethod)//接收委托调用
{
int i;
int j;
int temp;
for(i = items.Length-1;i>=0;i--)
{
for(j = 1;j<=i;j++)
{
if(comparisonMethod(items[j-1],items[j]))//使用委托
{
temp = items[j - 1];
items[j - 1] = items[j];
items[j] = temp;
}
}
}
}
public static bool GreaterThan(int first, int second)//需要委托的函数
{
return first > second;
}
static void Main()
{
int[] items = new int[100];
Random random = new Random();
for(int i = 0;i<items.Length;i++)
{
items[i] = random.Next(int.MinValue, int.MaxValue);
}
BubbleSort(items, GreaterThan);//委托过去!
for(int i = 0;i<items.Length;i++)
{
Console.WriteLine(items[i]);
}
}
}
以上就是简易的委托方法啦~
但是我们要问了,这种写法好麻烦,又要定义又要声明又要调用。有没有更简单的办法实现委托呢?
当然有啦!
我们不是嫌绑定函数繁琐吗?不!要!啦!
static void Main()
{
int[] items = new int[100];
Random random = new Random();
ComparisonHandler comparisonMethod;
for(int i = 0;i<items.Length;i++)
{
items[i] = random.Next(int.MinValue, int.MaxValue);
}
comparisonMethod =
delegate(int first, int second)
{
return first < second;
};
BubbleSort(items, comparisonMethod);
for(int i = 0;i<items.Length;i++)
{
Console.WriteLine(items[i]);
}
}
多的函数不!要!啦!不用绑定,直接在运行过程中写~
但是这还不是极限!
我们声明都不要啦!直接写!
<span style="white-space:pre"> </span>static void Main()
{
int[] items = new int[100];
Random random = new Random();
for(int i = 0;i<items.Length;i++)
{
items[i] = random.Next(int.MinValue, int.MaxValue);
}
BubbleSort(items, delegate(int first, int second)
{
return first < second;
});
for(int i = 0;i<items.Length;i++)
{
Console.WriteLine(items[i]);
}
}
但是这样写了之后你肯定不爽!为什么我们还要定义一个委托呢?明明都没有使用它都是直接写的。对啦,我们可以使用系统的泛型委托:Func<>和Action<>,前者是有返回值的委托,后者无返回值。
public static void BubbleSort(
int[] items,Func<int,int,bool> comparisonMethod)
上面的那个函数声明我们可以这样写啦!
Func的最后一个参数是返回值,前面两个是接收值。
但是这样存在瑕疵,因为委托名字被我们省略了,我们无法知道他的意思,这对于可读性是一个大大的伤害,并且系统委托并不能兼容自定义委托,即你不能将Func<int,int,bool>赋给一个ComparisonHandler变量,即使他们俩都是相同的含义。
当然,这样写之后,还有更简单的lambda表达式=>
比如刚刚那个可以这样写:
<span style="white-space:pre"> </span>BubbleSort(items, (first, second) =>
{
return first > second;
});
这样写非常简单,谓之匿名函数,匿名函数支持自动识别参数类型。
以上,如果有错,欢迎指正!