动态创建函数
大多数同学,都或多或少的使用过。回顾下c#中动态创建函数的进化:
C# 1.0中:
1 2 3 4 5 6 7 8 9 10 |
public delegate string DynamicFunction(string name); public static DynamicFunction GetDynamicFunction() { return GetName; } static string GetName(string name) { return name; } var result = GetDynamicFunction()("mushroom"); |
3.0写惯了是不是看起来很繁琐、落后。 刚学委托时,都把委托理解成函数指针,也来看下用函数指针实现的:
1 2 3 4 5 6 7 8 9 10 11 |
char GetName(char p); typedef char (*DynamicFunction)(char p); DynamicFunction GetDynamicFunction() { return GetName; } char GetName(char p) { return p; }; char result = GetDynamicFunction()('m'); |
对比起来和c# 1.0几乎一模一样了(引用/指针差别),毕竟是同一家族的。
C# 2.0中,增加匿名函数:
1 2 3 4 5 |
public delegate string DynamicFunction(string name); DynamicFunction result2 = delegate(string name) { return name; }; |
C# 3.0中,增加Lambda表达式,华丽的转身:
1 2 3 4 5 |
public static Func<string, string> GetDynamicFunction() { return name => name; } var result = GetDynamicFunction()("mushroom"); |
匿名函数不足之处
虽然增加Lambda表达式,已经极大简化了我们的工作量。但确实有些不足之处:
1 |
var result = name => name; |
这些写编译时是报错的。因为c#本身强类型语言的,提供var语法糖只是为了省去声明确定类型的工作量。 编译器在编译时必须能够完全推断出各参数的类型才行。代码中的name参数类型,显然在编译时无法推断出来的。
1 2 3 |
var result = (string name) => name; Func<string, string> result2 = (string name) => name; Expression<Func<string, string>> result3 = (string name) => name; |
上面直接声明name类型呢,很遗憾这样也是报错的。代码中已经给出答案了,编译器推断不出右边表达式是属于Func<string, string>类型还是Expression<Func<string, string>>类型。
.0中:
3.0写惯了是不是看起来很繁琐、落后。 刚学委托时,都把委托理解成函数指针,也来看下用函数指针实现的:
对比起来和c# 1.0几乎一模一样了(引用/指针差别),毕竟是同一家族的。 C# 2.0中,增加匿名函数:
C# 3.0中,增加Lambda表达式,华丽的转身:
匿名函数不足之处虽然增加Lambda表达式,已经极大简化了我们的工作量。但确实有些不足之处:
这些写编译时是报错的。因为c#本身强类型语言的,提供var语法糖只是为了省去声明确定类型的工作量。 编译器在编译时必须能够完全推断出各参数的类型才行。代码中的name参数类型,显然在编译时无法推断出来的。
上面直接声明name类型呢,很遗憾这样也是报错的。代码中已经给出答案了,编译器推断不出右边表达式是属于Func<string, string>类型还是Expression<Func<string, string>>类型。
|