=> 是什么?在 C# 中的属性签名中赋值 [英] What is the => assignment in C# in a property signature

查看:33
本文介绍了=> 是什么?在 C# 中的属性签名中赋值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一些代码,上面写着

public int MaxHealth =>内存[地址].IsValid ?Memory[地址].Read(Offs.Life.MaxHp):0;

现在我对 Lambda 表达式有点熟悉了.我只是没有看到它以这种方式使用它.

上面的语句和

有什么区别

public int MaxHealth = x ?y:z;

解决方案

您正在查看的是 表达式主体成员 不是 lambda 表达式.

当编译器遇到一个以表达式为主体的属性成员时,它本质上会将其转换为这样的getter:

public int MaxHealth{得到{返回内存[地址].IsValid?Memory[地址].Read(Offs.Life.MaxHp):0;}}

(您可以通过将代码注入一个名为 a>

Expression-bodied 成员 - 就​​像大多数 C# 6 特性一样 - 只是 语法糖.这意味着它们不提供通过现有功能无法实现的功能.相反,这些新功能允许使用更具表现力和简洁的语法

如您所见,表达式主体成员有一些使属性成员更紧凑的快捷方式:

  • 不需要使用return语句,因为编译器可以推断出你想要返回表达式的结果
  • 无需创建语句块,因为主体只是一个表达式
  • 没有必要使用 get 关键字,因为它是由表达式主体成员语法的使用所暗示的.

我将最后一点加粗,因为它与您的实际问题相关,我现在将回答.

...之间的区别

//表达式主体的成员属性public int MaxHealth =>X ?y:z;

还有……

//带有字段初始值设定项的字段公共 int MaxHealth = x ?y:z;

是一样的区别...

public int MaxHealth{得到{返回 x ?y:z;}}

还有……

public int MaxHealth = x ?y:z;

这 - 如果您了解属性 - 应该很明显.

不过要明确一点:第一个列表是一个在引擎盖下带有 getter 的属性,每次您访问它时都会调用它.第二个列表是一个带有字段初始值设定项的字段,当类型被实例化时,它的表达式只计算一次.

这种语法差异实际上非常微妙,可能会导致陷阱",Bill Wagner 在一篇题为 "AC# 6 问题:初始化与表达式实体成员".

虽然表达式主体成员是 lambda 表达式-like,但它们不是 lambda 表达式.根本区别在于 lambda 表达式会生成委托实例或表达式树.表达式主体成员只是编译器在幕后生成属性的指令.相似度(或多或少)以箭头(=>)开始和结束.

我还要补充一点,表达式主体成员不限于属性成员.他们为所有这些成员工作:

  • 属性
  • 索引器
  • 方法
  • 运营商

添加在 C# 7.0

但是,它们不适用于这些成员:

  • 嵌套类型
  • 活动
  • 字段

I came across some code that said

public int MaxHealth => 
         Memory[Address].IsValid ? 
         Memory[Address].Read<int>(Offs.Life.MaxHp) : 
         0;

Now I am somewhat familiar with Lambda expressions. I just have not seen it used it this way.

What would be the difference between the above statement and

public int MaxHealth  = x ? y:z;

解决方案

What you're looking at is an expression-bodied member not a lambda expression.

When the compiler encounters an expression-bodied property member, it essentially converts it to a getter like this:

public int MaxHealth
{
    get
    {
        return Memory[Address].IsValid ? Memory[Address].Read<int>(Offs.Life.MaxHp) : 0;
    }
}

(You can verify this for yourself by pumping the code into a tool called TryRoslyn.)

Expression-bodied members - like most C# 6 features - are just syntactic sugar. This means that they don’t provide functionality that couldn't otherwise be achieved through existing features. Instead, these new features allow a more expressive and succinct syntax to be used

As you can see, expression-bodied members have a handful of shortcuts that make property members more compact:

  • There is no need to use a return statement because the compiler can infer that you want to return the result of the expression
  • There is no need to create a statement block because the body is only one expression
  • There is no need to use the get keyword because it is implied by the use of the expression-bodied member syntax.

I have made the final point bold because it is relevant to your actual question, which I will answer now.

The difference between...

// expression-bodied member property
public int MaxHealth => x ? y:z;

And...

// field with field initializer
public int MaxHealth = x ? y:z;

Is the same as the difference between...

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

And...

public int MaxHealth = x ? y:z;

Which - if you understand properties - should be obvious.

Just to be clear, though: the first listing is a property with a getter under the hood that will be called each time you access it. The second listing is is a field with a field initializer, whose expression is only evaluated once, when the type is instantiated.

This difference in syntax is actually quite subtle and can lead to a "gotcha" which is described by Bill Wagner in a post entitled "A C# 6 gotcha: Initialization vs. Expression Bodied Members".

While expression-bodied members are lambda expression-like, they are not lambda expressions. The fundamental difference is that a lambda expression results in either a delegate instance or an expression tree. Expression-bodied members are just a directive to the compiler to generate a property behind the scenes. The similarity (more or less) starts and end with the arrow (=>).

I'll also add that expression-bodied members are not limited to property members. They work on all these members:

  • Properties
  • Indexers
  • Methods
  • Operators

Added in C# 7.0

However, they do not work on these members:

  • Nested Types
  • Events
  • Fields

这篇关于=> 是什么?在 C# 中的属性签名中赋值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆