我遇到了一些代码说
public int MaxHealth =>
Memory[Address].IsValid ?
Memory[Address].Read<int>(Offs.Life.MaxHp) :
0;
现在我对 Lambda 表达式有些熟悉了。我只是没有看到它以这种方式使用它。
上面的语句和
有什么区别public int MaxHealth = x ? y:z;
最佳答案
您正在查看的是 expression-bodied member不是 lambda 表达式。
当编译器遇到表达式主体的 property 成员时,它实际上会将其转换为如下所示的 getter:
public int MaxHealth
{
get
{
return Memory[Address].IsValid ? Memory[Address].Read<int>(Offs.Life.MaxHp) : 0;
}
}
(您可以通过将代码输入名为 TryRoslyn 的工具来自行验证这一点。)
表达式主体成员 - 像大多数 C# 6 功能一样 - 只是 syntactic sugar .这意味着它们不提供无法通过现有功能实现的功能。相反,这些新功能允许使用更具表现力和简洁的语法
如您所见,expression-bodied 成员有一些快捷方式可以使属性成员更紧凑:
- 不需要使用
return
语句,因为编译器可以推断出您想要返回表达式的结果 - 不需要创建语句 block ,因为主体只有一个表达式
- 不需要使用
get
关键字,因为它是通过使用表达式体成员语法暗示的。
我将最后一点加粗是因为它与我现在要回答的实际问题相关。
...之间的区别
// expression-bodied member property
public int MaxHealth => x ? y:z;
还有……
// field with field initializer
public int MaxHealth = x ? y:z;
相同的区别...
public int MaxHealth
{
get
{
return x ? y:z;
}
}
还有……
public int MaxHealth = x ? y:z;
哪个 - 如果您了解属性 - 应该是显而易见的。
但要明确一点:第一个 list 是一个属性,其内部有一个 getter,您每次访问它时都会调用它。第二个 list 是一个带有字段初始值设定项的字段,当类型被实例化时,其表达式仅被计算一次。
语法上的这种差异实际上非常微妙,可能会导致 Bill Wagner 在题为 "A C# 6 gotcha: Initialization vs. Expression Bodied Members" 的帖子中描述的“问题”。 .
虽然 expression-bodied 成员是 lambda 表达式-类似,但它们不是 lambda 表达式。根本区别在于 lambda 表达式生成委托(delegate)实例或表达式树。表达式体成员只是编译器在幕后生成属性的指令。相似性(或多或少)以箭头 (=>
) 开始和结束。
我还要补充一点,expression-bodied 成员不限于属性成员。他们在所有这些成员上工作:
- 属性
- 索引器
- 方法
- 运营商
加入 C# 7.0
但是,它们不适用于这些成员:
- 嵌套类型
- 事件
- 领域
关于c# - => 运算符在属性中意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31764532/