官方定义
委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。 在实例化委托时,你可以将其实例与任何具有兼容签名和返回类型的方法相关联。 你可以通过委托实例调用方法。
个人理解
委托就是能够将方法当成一个参数传到方法内,比如你声明了一个函数,你想让这个函数接受字符串类型的参数,那么你会想到string,那么如果你想让这个函数接受一个函数作为参数应该怎么做呢,此时就用到了为委托。
demo
class Program
{
public delegate void Del(string message);//定义委托类型,委托在c#中跟自定义类型是一个级别的
// Create a method for a delegate.
/// <summary>
/// 准备函数,函数要与委托签名保持一致。
/// </summary>
/// <param name="message"></param>
public static void DelegateMethod(string message)
{
Console.WriteLine(message);
}
static void Main(string[] args)
{
// Instantiate the delegate.
Del handler = DelegateMethod;//将函数赋值给委托实例
// Call the delegate.
handler("Hello World");
Console.ReadKey();
}
}
普通变量存的是数据,委托实例存的是行为
.net中定义了泛型委托action(无返回值)和func(有返回值),所以在实际开发中一般不用自定义委托类型。
class Program
{
static void Main(string[] args)
{
Action f1 = F1;
f1();
Action<string> f2 = F2;
f2("F2");
Func<string> f3 = F3;
string s3 = f3();
Func<string, string> f4 = F4;
string s4 = f4("f4");
Console.WriteLine(s3);
Console.WriteLine(s4);
Console.ReadKey();
}
static void F1()
{
Console.WriteLine("This is F1");
}
static void F2(string s)
{
Console.WriteLine($@"This is {s}");
}
static string F3()
{
return "This is F1";
}
static string F4(string s)
{
return $@"This is {s}";
}
}
委托变量不仅可以指向普通方法,还可以指向匿名方法。
class Program
{
static void Main(string[] args)
{
//匿名方法
Action f6 = delegate ()
{
Console.WriteLine("这是一个匿名方法");
};
f6();
Action<string, int> f2 = delegate (string n, int i)
{
Console.WriteLine($@"n={n},i={i}");
};
Func<int, int, string> f5 = delegate (int i1, int i2)
{
return $"{i1}+{i2}={i1 + i2}";
};
string s = f5(1, 2);
}
}
匿名方法可以写成lambda表达式,可以省略参数数据类型,因为编译能根据委托类型推断出参数的类型,用=>引出来方法体,delegate不可以
internal class Program
{
static void Main(string[] args)
{
//lamdba表达式
Func<int, int, string> f1 = (i1, i2) =>
{
return $"{i1}+{i2}={i1 + i2}={i1 + i2}";
};
//如果委托没有返回值,且方法体只有一行代码,可省略{ }
Action<int, string> a1 = (age, name) => Console.WriteLine($"年龄{age},姓名{name}");
a1(18, "test");
//如果 => 之后的方法体中只有一行代码,且方法有返回值,那么可以省略方法体的{ }以及return。
Func<int, int, string> f3 = (i1, i2) => $"{i1}+{i2}={i1 + i2}";
//如果只有一个参数,参数的()可以省略。
Action<string> f7 = s => Console.WriteLine(s);
Func<int, bool> f45 = i => i > 5;
}
}
lamada表达式是个什么呢?
首先不是委托,委托是类型,也不是委托的实例,只是一个方法,实际上是一个类中类,里面的internal方法,然后被绑定到静态的委托类型字段
lamada的注册是去不掉的