使用 => C# 设置 getter
Set a getter using => C#
我可以简化这个吗...
public class Foo : FooBase
{
public override Valor Nome
{
get
{
return new Valor
{
ValorEntrada = "agência centro"
};
}
}
}
...像这样的事情?
public class Foo : FooBase
{
public override Valor Nome => Valor.ValorEntrada = "agência centro";
}
Valor
有一个名为 ValorEntrada
的 属性,它接收一个 string
。
是的。但是您仍然需要带有对象初始化程序的 new
运算符...
public class Foo : FooBase
{
public override Valor Nome => new Valor { ValorEntrada = "agência centro" };
}
...但是 这是一个糟糕的设计。
假设您的 Valor
类型是 class
而不是 struct
,然后在 属性 中返回 new Valor
- getter 意味着可能不必要的托管堆对象分配。
- 虽然分配“便宜”(我个人不会这么说),但 GC 的成本却不是。
- 在 .NET 中,无论包含对象的状态如何,属性-getters 都应该始终没有副作用并且始终可以安全使用。虽然示例代码中似乎没有任何副作用,但它 确实 打破了调用者对 对象身份.
的期望
- 例如,这就是 属性 的行为方式,我认为这违反了预期:
Foo foo = new Foo();
Valor v1 = foo.Nome;
Valor v2 = foo.Nome;
Console.WriteLine( Object.ReferenceEquals( v1, v2 ) ); // "False"
您正在使用对象初始化器来设置看起来像 必需的 属性 而不是传递 "agência centro"
字符串通过构造函数参数表明您的 Valor
class 是可变的。
鉴于以上几点,这很糟糕。
因为这意味着这会发生:
Foo foo = new Foo();
foo.Nome.ValorEntrada = "x";
Console.WriteLine( foo.Nome.ValorEntrada ); // This prints "agência centro" instead of "x"
更好的选择:
更好的解决方案取决于您的 Valor
class 究竟代表什么,以及 Nome
属性 的用途。
如果父 class 打算用作工厂,那么您应该使用一种方法,而不是 属性,这样您就不会破坏任何假设或 通过使用 属性:
强加的隐含合同
public Valor CreateNewValor() => new Valor { ValorEntrada = "agência centro" };
如果 Valor
类型应该是不可变的,那么您应该使用构造函数填充它并将其存储在只读字段(或只读自动 属性)中。使用 static
字段很可能也是合适的,因为拥有相同不可变对象的多个副本毫无意义:
private static readonly Valor _instance = new Valor( valorEntrada: "agência centro" );
public override Valor Nome => _instance;
我可以简化这个吗...
public class Foo : FooBase
{
public override Valor Nome
{
get
{
return new Valor
{
ValorEntrada = "agência centro"
};
}
}
}
...像这样的事情?
public class Foo : FooBase
{
public override Valor Nome => Valor.ValorEntrada = "agência centro";
}
Valor
有一个名为 ValorEntrada
的 属性,它接收一个 string
。
是的。但是您仍然需要带有对象初始化程序的 new
运算符...
public class Foo : FooBase
{
public override Valor Nome => new Valor { ValorEntrada = "agência centro" };
}
...但是 这是一个糟糕的设计。
假设您的
Valor
类型是class
而不是struct
,然后在 属性 中返回new Valor
- getter 意味着可能不必要的托管堆对象分配。- 虽然分配“便宜”(我个人不会这么说),但 GC 的成本却不是。
- 在 .NET 中,无论包含对象的状态如何,属性-getters 都应该始终没有副作用并且始终可以安全使用。虽然示例代码中似乎没有任何副作用,但它 确实 打破了调用者对 对象身份. 的期望
- 例如,这就是 属性 的行为方式,我认为这违反了预期:
Foo foo = new Foo(); Valor v1 = foo.Nome; Valor v2 = foo.Nome; Console.WriteLine( Object.ReferenceEquals( v1, v2 ) ); // "False"
您正在使用对象初始化器来设置看起来像 必需的 属性 而不是传递
"agência centro"
字符串通过构造函数参数表明您的Valor
class 是可变的。鉴于以上几点,这很糟糕。
因为这意味着这会发生:
Foo foo = new Foo(); foo.Nome.ValorEntrada = "x"; Console.WriteLine( foo.Nome.ValorEntrada ); // This prints "agência centro" instead of "x"
更好的选择:
更好的解决方案取决于您的 Valor
class 究竟代表什么,以及 Nome
属性 的用途。
如果父 class 打算用作工厂,那么您应该使用一种方法,而不是 属性,这样您就不会破坏任何假设或 通过使用 属性:
强加的隐含合同public Valor CreateNewValor() => new Valor { ValorEntrada = "agência centro" };
如果
Valor
类型应该是不可变的,那么您应该使用构造函数填充它并将其存储在只读字段(或只读自动 属性)中。使用static
字段很可能也是合适的,因为拥有相同不可变对象的多个副本毫无意义:private static readonly Valor _instance = new Valor( valorEntrada: "agência centro" ); public override Valor Nome => _instance;