C# 你如何组织你的支持领域?(样式/图案)
c#3.0为我们提供了带有编译器生成的支持字段的getter和setter——这非常好,但是很多时候您仍然需要使用支持字段 在一个完美的世界里(观点),你可以做如下事情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
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;