C# 你如何组织你的支持领域?(样式/图案)

C# 你如何组织你的支持领域?(样式/图案),c#,coding-style,C#,Coding Style,c#3.0为我们提供了带有编译器生成的支持字段的getter和setter——这非常好,但是很多时候您仍然需要使用支持字段 在一个完美的世界里(观点),你可以做如下事情 class MyClass { ... stuff ... public string MyProperty { private string _myBackingField = "Foo"; get { return _myBackingField; } set { _myBackingF

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; }
  }
}

有没有人有接近这一点的建议或技巧?或者换一种方式——什么是使支持字段和属性保持组织的最清晰的方式。

我倾向于将支持字段放在顶部,但我也使用方法变量来实现这一点。也许这是一些旧语言的延续,在这些语言中,变量声明始终是第一步,但对我来说,它似乎比根据需要内联声明变量更有条理

如果您不喜欢在顶部声明变量,我见过的最接近您的“理想”风格的是:

private int _integer1 = 0;
public int Integer1 
{
    get {return _integer1;}
    set {_integer1 = value;}
}
我还是喜欢

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; }
  }
}
如果缺乏邻近性困扰您,您可以将每个属性的支持字段置于it服务属性之上

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; }
  }
}
你为什么要把“…东西…”放在地产和田地之间?我坚信要尽可能地将紧密耦合的事物保持在一起:

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; }
}
显然,某种允许默认设置的自动道具语法在这里是很好的,但是我不需要它,所以我不希望很快会用到它。它不能解决一个足够大的问题而值得付出很多努力……

我同意OP的“完美世界”示例是有用的。自动属性不适用于延迟加载场景:

class MyClass 
{  
    ... stuff ...   
    public string MyProperty 
    {    
        private string _myBackingField;    
        get 
        { 
            if (_myBackingField == null)
            {
                myBackingField = ... load field ...;
            }
            return _myBackingField; 
        }    
        set { _myBackingField = value; }  
    }
}

事实上,我早就提出了这个问题。

实际上,这似乎并不重要

根据我的经验,一旦一个类通过了某个复杂度阈值(基本上是“平凡”和“非平凡”之间的阈值),我就不再通过在其源代码中滚动来浏览该类,而是通过使用Go To Definition和Find Usages来浏览该类

使用线性接近来暗示类成员之间的关系似乎是一个好主意,但我认为事实并非如此。如果我看到这个:

private string _Foo;
public string Foo 
{
    // arbitrarily complex get/set logic
}
含义很清楚:
\u Foo
仅由
Foo
属性使用。不过,这一暗示并不可靠。要确保类中没有操作
\u Foo
的代码,唯一的方法就是检查它。好吧,如果我不能依靠接近来告诉我任何事情,我为什么要关心接近呢

这些天,我只是从一开始就按字母顺序排列我的班级成员。这让我不用再去想那些无关紧要的事情(我应该把这个成员放在哪里,为什么我应该选择那个地方?)。

我更喜欢什么:

public int Integer1 
{
    get {return _integer1;}
    set {_integer1 = value;}
}
private int _integer1 = 0;
为什么?

  • 因为财产要多得多 比后场更重要,所以 它应该被理解为第一个
  • 如果你评论你的财产,什么读起来更好
这个

private int\u integer1=0;
///
///这是我的财产,好好享受吧
///
公共整数1
{
获取{return\u integer1;}
设置{u integer1=value;}
}

///
///这是我的财产,好好享受吧
///
公共整数1
{
获取{return\u integer1;}
设置{u integer1=value;}
}
私有整数_integer1=0;

末尾带有backing字段的approchach更易于阅读。将属性应用于属性也是如此。

当我不能使用自动实现的属性时,这正是我所做的。@Alex,因为我的个人偏好令人憎恶,值得你明确反对,我也非常关心/对于你的问题,这是一个很好的例子吗?也许一个例子中的Auto属性不立即适用会更明显。你建议的语法的优点是,backing字段的范围将限制在wrapping属性中。使用该属性设置默认值会对性能造成多大的影响,与其直接在代码中设置支持字段,还不如直接在代码中设置支持字段。来自MSDN:“DefaultValueAttribute不会导致成员自动初始化为该属性的值。您必须在代码中设置初始值。”;构造函数是设置字段的代码。
[DefaultValue]
只是我在自我记录默认值时的习惯力量。延迟加载实际上是激发这个问题的用例。可能是处理它的最佳方式。如果您也是使用自动摘要标记的人之一,他们往往会妨碍相邻属性的使用(如后一种情况)。添加文档时,属性上方的支持字段会变得混乱。添加
\\\etc.
时,必须在备份字段和属性之间执行此操作。。。
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;