

C# 7.0 新特性:本地方法 - 冠军
source link: http://www.cnblogs.com/haogj/p/7636915.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C# 7.0:本地方法
VS 2017 的 C# 7.0 中引入了本地方法,本地方法是一种语法糖,允许我们在方法内定义本地方法。更加类似于函数式语言,但是,本质上还是基于面向对象实现的。
1. 本地方法
先看一个示例:
1 using static System.Console; 2 3 namespace UseLocalFunctions 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 void Add(int x, int y) 10 { 11 WriteLine($"Sum of {x} and {y}: is {x + y}"); 12 } 13 14 void Multiply(int x, int y) 15 { 16 WriteLine($"Multiply of {x} and {y} is: {x * y}"); 17 Add(30, 10); 18 } 19 20 Add(10, 30); 21 Multiply(40, 30); 22 23 ReadLine(); 24 } 25 } 26 }
在此示例中,在 Main 方法内,嵌套定义了两个方法:Add 和 Multiply。这个方法可以在 Main 方法内被使用。这种方法被称为本地方法。英文称为:Local function.
使用 ILDasm 工具,可以看到编译之后的结果。
这两个本地方法被翻译成了两个静态的私有方法,它只能在定义的方法内被调用。
本地方法的语法定义为:
<modifiers: async | unsafe> <return-type> <method-name> <parameter-list>
方法的修饰符只有两种:async 和 unsafe,所有的本地方法都是私有的
- 如果您使用了 private 修饰,会收到 编译器的错误提示:error CS0106, "The modifier 'static' is not valid for this item."
- 如果您使用了 static,会收到编译器的错误提示:error CS0106, "The modifier 'static' is not valid for this item."
2. 带有返回类型的本地方法
本地方法也可以带有返回类型。如果类型用错的话,Visual Studio 可以给出提示。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 PrintStudentMarks(101, 6 new Subject 7 { 8 SubjectName = "Math", 9 Marks = 96 10 }, new Subject 11 { 12 SubjectName = "physics", 13 Marks = 88 14 }, new Subject 15 { 16 SubjectName = "Chem", 17 Marks = 91 18 }); 19 20 ReadLine(); 21 } 22 23 public static void PrintStudentMarks(int studentId, params Subject[] subjects) 24 { 25 WriteLine($"Student Id{studentId} Total Marks: {CalculateMarks()}"); 26 WriteLine($"Student wise marks"); 27 foreach(var subject in subjects) 28 { 29 WriteLine($"Subject Name: {subject.SubjectName}\t Marks: {subject.Marks}"); 30 } 31 32 decimal CalculateMarks() 33 { 34 decimal totalMarks = 0; 35 foreach(var subject in subjects) 36 { 37 totalMarks += subject.Marks; 38 } 39 40 return totalMarks; 41 } 42 } 43 44 public class Subject 45 { 46 public string SubjectName 47 { 48 get; set; 49 } 50 51 public decimal Marks 52 { 53 get; set; 54 } 55 } 56 }
3. 使用本地方法实现递归
本地方法不需要维护调用堆栈,而递归方法需要维护调用堆栈,本地方法效率更高。下面的示例演示了两种方法的区别。
注意:该示例使用了类型 BigInteger ,需要添加对程序集 System.Numeric.dll 的引用。
代码如下。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Stopwatch watch = new Stopwatch(); 6 watch.Start(); 7 BigInteger f1 = GetFactorialUsingLocal(9000); 8 watch.Stop(); 9 WriteLine($"Using local function: {watch.ElapsedTicks}"); 10 11 watch.Reset(); 12 watch.Start(); 13 BigInteger f2 = GetFactorial(9000); 14 watch.Stop(); 15 WriteLine($"Using recursive function: {watch.ElapsedTicks}"); 16 } 17 18 private static BigInteger GetFactorialUsingLocal(int number) 19 { 20 if (number < 0) 21 throw new ArgumentException("negative number", nameof(number)); 22 else if (number == 0) 23 return 1; 24 BigInteger result = number; 25 while (number > 1) 26 { 27 Multiply(number - 1); 28 number--; 29 } 30 31 void Multiply(int x) => result *= x; 32 return result; 33 } 34 35 private static BigInteger GetFactorial(int number) 36 { 37 if (number < 0) 38 throw new ArgumentException("nagative number", nameof(number)); 39 return number == 0 ? 1 : number * GetFactorial(number - 1); 40 } 41 }
在我的机器上,结果如下:
Using local function: 181770
Using recursive function: 456602
可以看到两者之间的性能差异。
此时,为了传递 result ,在生成的代码中,编译器会自动做一些额外的工作。
4. 本地方法与 Lambda 的比较
当创建 Lambda 的时候,将会创建一个委托,这需要内存分配,因为委托是一个对象。而本地方法则不需要,它是一个真正的方法。
另外,本地方法可以更为有效地使用本地变量,Lambda 将变量放到类中,而本地方法可以使用结构,而不使用内存分配。
这意味着调用本地方法更为节约且可能内联。
2. 本地方法可以递归
Lambda 也可以实现递归,但是代码丑陋,您需要先赋予 lambda 为 null。本地方法可以更为自然地递归。
3. 本地方法可以使用泛型
Lambda 不能使用泛型。这是因为需要赋予一个实例类型的变量。
4. 本地方法可以实现迭代器
Lambda 不能使用 yield return (以及 yield break)关键字,以实现 IEnumerable<T> 返回函数。本地方法可以。
5. 本地方法更为易读
5. 其它资源:
Recommend
-
74
最全最好用的动效落地方法,都帮你总结好了(上)
-
51
-
8
产品公开课|如何让产品避免沦为“烂尾楼”?这套B端产品落地方法你值得拥有 | 人人都是产品经理今天,又是为B端产品落地交付头秃的一天…… 业务调研做了好几次才确定的流程,需求评审时业务部又临时加一个流程。 辛辛苦苦加班一周进行产品设计...
-
8
产品公开课|如何让产品避免沦为“烂尾楼”?这套B端产品落地方法你值得拥有 | 运营派 ¥1 ¥68...
-
9
JAVA是可以调用本地方法的,官方提供的调用方式叫做JNI,全称叫做java native interface。要想使用JNI,我们需要在JAVA代码中定义native方法,然后通过javah命令创建C语言的头文件,接着使用C或者C++语言来实现这个头文件中的方法,编译源代码,最后将编译后的...
-
5
相信每个程序员都有一个成为C++大师的梦想,毕竟C++程序员处于程序员鄙视链的顶端,他可以俯视任何其他语言的程序员。 但事实情况是,无数的程序员从小白到放弃,鉴于C++的难度,最后都投入了java的怀抱。JAVA以他宽广的胸怀接纳了一众无法登顶C++的程序...
-
8
不管是JNI还是JNA,最终调用的都是native的方法,但是对于JAVA程序来说,一定需要一个调用native方法的入口,也就是说我们需要在JAVA方法中定义需要调用的native方法。 对于JNI来说,我们可以使用native关键字来定义本地方法。那么在JNA中有那些在JAVA代...
-
5
不管是JNI还是JNA,最终调用的都是native的方法,但是对于JAVA程序来说,一定需要一个调用native方法的入口,也就是说我们需要在JAVA方法中定义需要调用的native方法。 对于JNI来说,我们可以使用native关键字来定义本地方法。那么在JNA中有那些在JAVA代...
-
10
《DFM急诊室》EP4.1 EMC高频接地与安规接地方法的区别-模拟/电源-与非网
-
13
首页 > 原创干货 > 人才测评...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK