引用方法
在C++,函数指针只不过是一个指向内存位置的指针,它不是类型安全的。
C# 委托 定义了返回类型和参数的类型。委托类包含对方法的引用,还可以包含多个方法引用。
定义委托
public delegate double TwoLongsOp(long first, long second); public delegate string GetAString();
委托派生自 System.MulticastDelegate,而 System.MulticastDelegate 又派生自 System.Delegate。
public delegate string GetAString(); static void Main(string[] args) { int x = 10; Console.WriteLine(x.ToString()); GetAString stringFun = new GetAString(x.ToString); Console.WriteLine(stringFun()); } // 以下两种方法一样 stringFun(); stringFun.Invoke();
GetAString stringFun = new GetAString(x.ToString); GetAString stringFun2 = x.ToString;
委托它们类型是安全的,可以确保被调用的方法的签名是正确的。但它们不关心什么类型的对象上调用该方法,甚至不考虑该方法是静态方法,还是实例方法。
class MyClass { public static string getStr() { return "Hello"; } } static void Main(string[] args) { GetAString stringFun = MyClass.getStr; Console.WriteLine(stringFun()); }
委托数组
GetAString[] stringFun = { MyClass.getStr }; Console.WriteLine(stringFun[0]());
泛型 Action<T> 委托表示引用一个 void 返回类型的方法。Action 可以调用 0 ~ 16 个参数的方法。
Func<T> 引用 带 返回类型的方法,Func可以调用 0 ~ 16 个参数的方法。
class MyClass { public static string getString(string s) { return "Hello "+ s; } public static void Call() { Console.WriteLine("Hello Call"); } } static void Main(string[] args) { Func<string, string> stringFun = MyClass.getString; Console.WriteLine(stringFun("Wo")); Action fun2 = MyClass.Call; fun2(); }
多播委托
存储两个方法的引用
增加 += 删除 -=
class MyClass { public static void Hello(string s) { Console.WriteLine("Hello " + s); } public static void Call(string s) { Console.WriteLine("Call " + s); } } static void Main(string[] args) { Action<string> action = MyClass.Hello; action += MyClass.Call; action("Zhao"); action -= MyClass.Call; action("Zhao2"); }
如果 Hello 方法报错了,第二个 Call 就不会执行了。可以用以下代替。
Action<string> action = MyClass.Hello; action += MyClass.Call; Delegate[] delegates = action.GetInvocationList(); foreach (Action<string> action2 in delegates) { try { action2("Python"); } catch (Exception) { } }
匿名方法
Action<string> action = delegate(string str) { Console.WriteLine("Anonymous " + str); }; Delegate[] delegates = action.GetInvocationList(); foreach (Action<string> action2 in delegates) { try { action2("Python"); } catch (Exception) { } }
匿名方法不能使用跳转语句(break、goto 或 continue)跳到该匿名方法的外部。匿名方法内部能访问不安全的代码。也不能使用 ref 和 out 参数。但可以使用匿名方法外部定义的其他变量。
lmadba
Action<string> action = str => Console.WriteLine("lambda " + str); Action<string> action2 = (str) => { Console.WriteLine("lambda " + str); };
匿名方法
int sum = 12; Func<int, int> fun = x => x + sum; Console.WriteLine(fun(12) + " " + sum);
时间: 2024-10-12 01:36:47