使用 => C# 设置 getter

Mar*_*Jr. -4 c# getter

我可以简化这个吗...

\n
public class Foo : FooBase\n{\n    public override Valor Nome\n    {\n        get\n        {\n            return new Valor\n            {\n                ValorEntrada = "ag\xc3\xaancia centro"\n            };\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

......这样的事情?

\n
public class Foo : FooBase\n{\n    public override Valor Nome => Valor.ValorEntrada = "ag\xc3\xaancia centro";\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Valor有一个名为 的属性ValorEntrada,它接收一个string.

\n

Dai*_*Dai 13

是的。但你仍然需要new带有对象初始化器的运算符......

\n
public class Foo : FooBase\n{\n    public override Valor Nome => new Valor { ValorEntrada = "ag\xc3\xaancia centro" };\n}\n
Run Code Online (Sandbox Code Playgroud)\n

...然而这是一个糟糕的设计。

\n
    \n
  • 假设您的Valor类型是 aclass而不是 a struct,那么返回new Valor属性 getter 意味着可能会进行不必要的托管堆对象分配。

    \n
      \n
    • 虽然分配很“便宜”(我个人不会这么说),但 GC 的成本却并非如此。
    • \n
    • 在 .NET 中,属性获取器应该始终无副作用并且始终可以安全使用,无论包含对象的状态如何。虽然示例代码中似乎没有任何副作用,但它确实打破了调用者对对象标识的期望。
    • \n
    • 例如,这就是该属性的行为方式,我认为这违反了预期:\n
      Foo foo = new Foo();\nValor v1 = foo.Nome;\nValor v2 = foo.Nome;\nConsole.WriteLine( Object.ReferenceEquals( v1, v2 ) ); // "False"\n
      Run Code Online (Sandbox Code Playgroud)\n
    • \n
    \n
  • \n
  • 事实上,您使用对象初始化程序来设置看起来像必需属性的内容,而不是"ag\xc3\xaancia centro"通过构造函数参数传递字符串,这表明您的Valor类是可变的。

    \n
      \n
    • 考虑到上述几点,这很糟糕。

      \n
    • \n
    • 因为这意味着这将会发生:

      \n
      Foo foo = new Foo();\nfoo.Nome.ValorEntrada = "x";\nConsole.WriteLine( foo.Nome.ValorEntrada ); // This prints "ag\xc3\xaancia centro" instead of "x"\n
      Run Code Online (Sandbox Code Playgroud)\n
    • \n
    \n
  • \n
\n

更好的选择:

\n

更好的解决方案取决于您的Valor类到底代表什么以及该Nome属性的用途。

\n
    \n
  • 如果父类旨在作为工厂,那么您应该使用方法,而不是属性,这样您就不会违反使用属性强加的任何假设或隐含契约:

    \n
    public Valor CreateNewValor() => new Valor { ValorEntrada = "ag\xc3\xaancia centro" };\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
  • 如果Valor类型应该是不可变的,那么您应该使用构造函数填充它并将其存储在只读字段(或只读自动属性)中。使用字段很可能也是合适的,static因为没有相同的不可变对象的多个副本:

    \n
    private static readonly Valor _instance = new Valor( valorEntrada: "ag\xc3\xaancia centro" );\n\npublic override Valor Nome => _instance;\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
\n