c#3.0为我们提供了带有编译器生成的支持字段的getter和setter - 这真的很棒,但是很多时候你仍然需要使用支持字段。
在一个完美的世界(意见)中,你可以做类似
的事情class MyClass {
... stuff ...
public string MyProperty {
private string _myBackingField = "Foo";
get { return _myBackingField; }
set { _myBackingField = value; }
}
}
而不是
class MyClass {
private string _myBackingField = "Foo";
... stuff ...
public string MyProperty {
get { return _myBackingField; }
set { _myBackingField = value; }
}
}
有没有人有接近这个的建议或技巧?或者换句话说 - 保持支持字段和属性的最清晰方式是什么。
答案 0 :(得分:5)
我倾向于将支持字段保持在顶部,但是我也使用方法变量。也许它是一些旧语言的延续,其中变量声明始终是第一步,但它似乎比我根据需要内联声明变量更有条理。
如果你不喜欢在顶部声明变量,那么我最接近你的“理想”风格的是:
private int _integer1 = 0;
public int Integer1
{
get {return _integer1;}
set {_integer1 = value;}
}
答案 1 :(得分:5)
我还是喜欢
class MyClass {
private string _myBackingField = "Foo";
private string _myOtherBackingField = "bar";
... stuff ...
public string MyProperty {
get { return _myBackingField; }
set { _myBackingField = value; }
}
public string MyOtherProperty {
get { return _myOtherBackingField; }
set { _myOtherBackingField = value; }
}
}
如果缺乏亲近感困扰您,您可以将每个房产的支持字段放在它所服务的房产之上。
class MyClass {
private string _myBackingField = "Foo";
public string MyProperty {
get { return _myBackingField; }
set { _myBackingField = value; }
}
private string _myOtherBackingField = "bar";
public string MyOtherProperty {
get { return _myOtherBackingField; }
set { _myOtherBackingField = value; }
}
}
答案 2 :(得分:1)
为什么要在物业和田地之间加上“...东西......”?我坚信要尽可能地保持紧密耦合的东西:
class MyClass {
... stuff ...
private string _myBackingField = "Foo";
public string MyProperty {
get { return _myBackingField; }
set { _myBackingField = value; }
}
}
除非必须:
,否则我也不会引入额外的字段BinaryFormatter
)序列化原因在给出的例子中,我只使用了一个汽车道具:
class MyClass {
... stuff ...
public MyClass() {
MyProperty = "Foo";
}
[DefaultValue("Foo")]
public string MyProperty { get;set; }
}
显然,某种允许默认的auto-prop语法在这里会很好,但我不需要它,所以我不希望它很快就会出现。它不能解决一个足够大的问题,值得付出很多努力......
答案 3 :(得分:1)
我同意OP的“完美世界”示例会很有用。自动属性不适用于延迟加载方案:
class MyClass
{
... stuff ...
public string MyProperty
{
private string _myBackingField;
get
{
if (_myBackingField == null)
{
myBackingField = ... load field ...;
}
return _myBackingField;
}
set { _myBackingField = value; }
}
}
事实上我前段时间提出了as a suggestion on Microsoft Connect。
答案 4 :(得分:1)
我更喜欢:
public int Integer1
{
get {return _integer1;}
set {_integer1 = value;}
}
private int _integer1 = 0;
为什么呢?
此
private int _integer1 = 0;
///<summary>
/// this is my property, enjoy it
///</summary>
public int Integer1
{
get {return _integer1;}
set {_integer1 = value;}
}
或
///<summary>
/// this is my property, enjoy it
///</summary>
public int Integer1
{
get {return _integer1;}
set {_integer1 = value;}
}
private int _integer1 = 0;
最后带有支持字段的approchach更具可读性。将属性应用于属性也是如此。
答案 5 :(得分:0)
在实践中,它似乎并不重要。
根据我的经验,一旦一个类通过了一定的复杂度阈值(基本上是“琐碎”和“非平凡”之间的门槛),我就不再通过在源头中滚动来浏览该类,我导航通过使用转到定义和查找用法。
使用线性接近来暗示关于类成员之间关系的事情似乎是个好主意,但我认为事实并非如此。如果我看到这个:
private string _Foo;
public string Foo
{
// arbitrarily complex get/set logic
}
含义很明确:_Foo
仅由Foo
属性使用。但这种含义并不可靠。我唯一能够确定类中没有操作_Foo
的代码的方法就是检查它。好吧,如果我不能依靠接近告诉我任何事情,我为什么要关心接近?
这些天,我只是从一开始就按字母顺序排列我的班级成员。这让我不必考虑某些事情(我应该把这个成员放在哪里,为什么我应该选择那个地方?)这并不重要。