HTML5技术

C# 7.0 新特性:本地方法 - 冠军

字号+ 作者:H5之家 来源:H5之家 2017-10-09 13:00 我要评论( )

C# 7.0:本地方法 VS 2017 的 C# 7.0 中引入了本地方法,本地方法是一种语法糖,允许我们在方法内定义本地方法。更加类似于函数式语言,但是,本质上还是基于面向对象实现的。 1. 本地方法 先看一个示例: System.Console; UseLocalFunctions 4 { 5 class Pro

C# 7.0:本地方法

VS 2017 的 C# 7.0 中引入了本地方法,本地方法是一种语法糖,允许我们在方法内定义本地方法。更加类似于函数式语言,但是,本质上还是基于面向对象实现的。

1. 本地方法

先看一个示例:

System.Console; UseLocalFunctions 4 { 5 class Program 6 { Main(string[] args) 8 { 9 void Add(int x, int y) 10 { ); 12 } Multiply(int x, int y) 15 { ); 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 { Main(string[] args) 4 { 5 PrintStudentMarks(101, 6 new Subject 7 { , 9 Marks = 96 10 }, new Subject 11 { , 13 Marks = 88 14 }, new Subject 15 { , 17 Marks = 91 18 }); 19 20 ReadLine(); 21 } PrintStudentMarks(int studentId, params Subject[] subjects) 24 { ); ); 27 foreach(var subject in subjects) 28 { ); 30 } CalculateMarks() 33 { 34 decimal totalMarks = 0; 35 foreach(var subject in subjects) 36 { 37 totalMarks += subject.Marks; 38 } totalMarks; 41 } 42 } Subject 45 { SubjectName 47 { 48 get; set; 49 } Marks 52 { 53 get; set; 54 } 55 } 56 }

     

     

    3. 使用本地方法实现递归

    本地方法不需要维护调用堆栈,而递归方法需要维护调用堆栈,本地方法效率更高。下面的示例演示了两种方法的区别。

    注意:该示例使用了类型 BigInteger ,需要添加对程序集 System.Numeric.dll 的引用。

    代码如下。

    1 class Program 2 { Main(string[] args) 4 { 5 Stopwatch watch = new Stopwatch(); 6 watch.Start(); 7 BigInteger f1 = GetFactorialUsingLocal(9000); 8 watch.Stop(); ); 10 11 watch.Reset(); 12 watch.Start(); 13 BigInteger f2 = GetFactorial(9000); 14 watch.Stop(); ); 16 } BigInteger GetFactorialUsingLocal(int number) 19 { 20 if (number < 0) ArgumentException(, nameof(number)); (number == 0) ; 24 BigInteger result = number; 25 while (number > 1) 26 { 27 Multiply(number - 1); 28 number--; 29 } Multiply(int x) => result *= x; 32 return result; 33 } BigInteger GetFactorial(int number) 36 { 37 if (number < 0) ArgumentException(, nameof(number)); 39 return number == 0 ? 1 : number * GetFactorial(number - 1); 40 } 41 }

     

    在我的机器上,结果如下:

    Using local function: 181770
    Using recursive function: 456602

    可以看到两者之间的性能差异。

    此时,为了传递 result ,在生成的代码中,编译器会自动做一些额外的工作。

     

    4. 本地方法与 Lambda 的比较 1. 性能

    当创建 Lambda 的时候,将会创建一个委托,这需要内存分配,因为委托是一个对象。而本地方法则不需要,它是一个真正的方法。

    另外,本地方法可以更为有效地使用本地变量,Lambda 将变量放到类中,而本地方法可以使用结构,而不使用内存分配。

    这意味着调用本地方法更为节约且可能内联。

    2. 本地方法可以递归

    Lambda 也可以实现递归,但是代码丑陋,您需要先赋予 lambda 为 null。本地方法可以更为自然地递归。

    3. 本地方法可以使用泛型

    Lambda 不能使用泛型。这是因为需要赋予一个实例类型的变量。

    4. 本地方法可以实现迭代器

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解 - 行动派Xdpie

      ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解 - 行动派Xdpie

      2017-09-15 17:05

    • HTML5新特性: 自定义属性前缀data-以及dataset的使用 - ghostwu

      HTML5新特性: 自定义属性前缀data-以及dataset的使用 - ghostwu

      2017-08-25 10:01

    • HTML5新特性:元素的classList属性与应用 - ghostwu

      HTML5新特性:元素的classList属性与应用 - ghostwu

      2017-08-24 17:00

    • .Net大局观(2).NET Core 2.0 特性介绍和使用指南 - L.P.Y

      .Net大局观(2).NET Core 2.0 特性介绍和使用指南 - L.P.Y

      2017-08-17 17:01

    网友点评