C# 表达式体属性与{get;set;}

C# 表达式体属性与{get;set;},c#,properties,automatic-properties,C#,Properties,Automatic Properties,当Visual Studio 2017为我生成属性时,它将始终使用新的表达式体属性,例如: private static string username; internal static string Username { get => username; set => username = value; } 使用这种样式比下面的样式有什么优势吗?还是只是偏好和可读性的问题 internal static string Username { get; set; } 我可以很快在第

当Visual Studio 2017为我生成属性时,它将始终使用新的表达式体属性,例如:

private static string username;
internal static string Username { get => username; set => username = value; }
使用这种样式比下面的样式有什么优势吗?还是只是偏好和可读性的问题

internal static string Username { get; set; }

我可以很快在第二种风格中看到一些优势:

  • 你打字少了
  • 可以快速阅读
  • 不要让读者认为能手或二传手在做一些特别的事情
  • 查找所有引用返回的结果较少
  • 编辑
    我错过了第一种风格的一个主要问题。见下面poke的答案。

    是的,有区别;实际上是一个大的。前面的解决方案将创建一个无限循环,因为属性getter和setter正在引用自身

    string Username { get => Username; set => Username = value; }
    
    这严格等同于以下内容(因为它只是语法上的糖分):

    因此属性
    Username
    的getter和setter都引用了成员
    Username
    ,该成员本身就是这个成员。因此,当您访问该成员时,它将永远重复调用自己,并且永远不会返回结果

    您可能打算执行以下操作:

    string _username;
    string Username { get => _username; set => _username = value; }
    
    现在您有了一个支持字段,您引用它来实际存储属性的值。这很好,对于更详细的getter和setter语法没有区别。它编译成同样的东西;只是C#6让你在这里变得简单了一点


    剩下的区别是显式支持字段与使用自动属性时自动创建的支持字段。是否要使用“自动”属性取决于您的样式,但一般来说,如果要手动创建相同的支持字段,则没有真正的理由不使用它们。当然,如果您没有将值存储在普通备份字段中和/或需要其他逻辑,那么您当然不能在此处使用自动属性。但是,无论如何,您可能不会得到表达式体属性。另请参见“自动属性”。

    表达式体语法在以下情况下使用起来很方便:

    仅获取或设置属性

    public DateTime Date => DateTime.Now;
    
    方法

    public IEnumerable<string> GetData => SomeMethodThatReturnData.Select(x => x.Name);
    

    用这个网站的名字来破坏你的程序没有什么好处。你是如何让Visual Studio生成递归属性的?哈,对不起。现在应该更好了。由于您现在修复了递归引用,这基本上只是重复了何时使用自动属性。至于表达式体属性部分,它将是的副本。如果我不清楚,很抱歉:我的问题是,人们是否可以基本上忘记{get;set;}并始终使用表达式体属性,或者是否有充分的理由不使用(例如,性能上的差异)我知道在某些特定情况下,表达式体属性更方便(例如,如果您只需要一个getter),这个问题现在已经得到了回答。非常感谢。“表达式求值器不是由编译器触发的。”–这是什么意思?@poke:C#编译器需要求值getter的主体(因为它也可能有一个复杂的表达式)。对于自动属性,编译器应该非常确定没有必要这样做。尽管我必须承认我错过了你指出的巨大差异。也许我的印象是错误的,因为就在今天(在另一篇SO文章中),我了解到自动getter-only属性现在可以分配给构造函数。显然,这是两件不同的事情,但对于代码的每个字符都是如此。编译器就是这样做的。您的措辞“expression evaluator”听起来似乎涉及。正确,这就是为什么我明确提到编译器,而不是运行时。在您的三个示例中,只有一个是表达式体属性。我正在查找有关表达式体用法的信息,注意到您的GetData方法没有括号。有没有一个c#引用可以帮助我理解这一点?@JamesLee它是一个表达式体只读(get-only)属性
    public IEnumerable<string> GetData => SomeMethodThatReturnData.Select(x => x.Name);
    
    public SomeClass(IRepository repository) => _repository = repository;