C#里 =>的用法

您所在的位置:网站首页 byallmeans的用法 C#里 =>的用法

C#里 =>的用法

2023-08-14 03:04| 来源: 网络整理| 查看: 265

问题

看到有人写这样的代码,这里的=>让人感到疑惑,我一直以为它是Lambda表达式的写法,跟C++的->类似,比较好理解,但是明显下面这里的代码不是属于Lambda表达式的范围

// 这里的MaxHealth1和MaxHealth2有什么区别? public class Health { // expression-bodied member property public int MaxHealth1 => x ? y:z; // field with field initializer public int MaxHealth2 = x ? y:z; };

为了解决这个问题,写下了这篇博客

C#里=>的两种用法

C#里的=>有两种用法:

用于Lambda表达式里,此时的=>被称为lambda operator用于expression-bodied member

第一种用法 第一种用法,比较好理解,其实就是Lambda表达式的写法,在C# 3到C# 5版本间,=>只有此种用法。此时的=>C++的lambda表达式里的->类似,举个例子:

// 声明一个函数指针的对象, 也就是委托, 其函数签名为string f(Person) Func nameProjection = p => p.Name; // 上面这句, 等同于: Func nameProjection = delegate (Person p) { return p.Name; };

注意这里的Func,最后面的代表函数的返回类型,前面的代表函数的参数,Func只是.NET提供的委托模板:

namespace System { // Summary: // Encapsulates a method that has one parameter and returns a value of the type public delegate TResult Func(T arg); }

第二种用法 在C# 6的版本里,=>开始用于expression-bodied members,代码如下:

public int MaxHealth1 => x ? y:z;

而这种语法,是一种Syntax Sugar,上面的代码等同于下面的:

public int MaxHealth1 { get { return x ? y:z; } }

所以,上面的MathHealth1和MathHealth2的区别,其实就是C#里Property和Field的区别:

MaxHealth1是一个Property,设置了getter,每次访问该值的时候,都会调用x?y:z表达式MathHeath2是一个Field,它的表达式只会在其初始化时计算一次

其实应该说的很清楚了,再举个例子:

class Program { public class A { public static int x;//默认初始化为0 public int X1 => x; public int X2 = x; } static void Main() { Console.WriteLine(A.x);// 0 A a = new A(); Console.WriteLine(a.X1);// 0 Console.WriteLine(a.X2);// 0 A.x = 5; Console.WriteLine(a.X1);// 5 Console.WriteLine(a.X2);// 0 A.x = 10; Console.WriteLine(a.X1);// 10 Console.WriteLine(a.X2);// 0 } }

可以看到,每次去取X1的值的时候,都会执行return x;这个表达式,所以上面的问题解决了。

参考资料: https://stackoverflow.com/questions/290061/what-does-the-syntax-in-c-sharp-mean/290063#290063 https://stackoverflow.com/questions/31764532/what-is-the-assignment-in-c-sharp-in-a-property-signature

一个小问题

写这个类的时候,编译报了错:

public class A { public int x;//默认初始化为0 public int X1 => x;//这一句是OK的 public int X2 = x;// 这一句编译报错 }

报错的信息如下:

A field initializer cannot reference the nonstatic field, method, or property

意思是,一个类里的field不可以用非static的field、method或property进行初始化,也就是说类里field要用静态成员或函数才可以为其初始化。

原因是,在C#里规定,不可以用一个instance variable作为另外一个instance varialble的初始值,因为这里无法保证哪一个变量是先初始化的。

顺便提一句,有意思的是,在C++里,类似的代码是可以运行的,因为C++里类的成员变量是按照声明顺序进行初始化的,代码如下:

#include class T { public: int c = a;// 可以成功编译和运行 int a = 3; int b = a; }; int main() { T t; std::cout get { return _myField; } set { _myField = value; } } // This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax // used to generate a private field for you public int AnotherProperty{get;set;} }

注意:field成员一般(或者说总是)被声明为private,C#3.0以后支持只写Property而不用在类里再写一个private的field,会自动生成对应的field

更多详情可以参考StackOverflow



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3