我们经常被告知我们应该通过为类字段制作getter和setter方法(C#中的属性)来保护封装,而不是将字段暴露给外部世界.
但是很多时候,一个字段只是用来保存一个值,并且不需要任何计算来获取或设置.对于这些,我们都会这样做:
public class Book
{
private string _title;
public string Title
{
get{ return _title; }
set{ _title = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,我有一个坦白,我不忍心写所有这些(真的,它不必写它,它不得不看它),所以我去流氓和使用公共领域.
然后是C#3.0,我看到他们添加了自动属性:
public class Book
{
public string Title {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
这更整洁,我很感激它,但是真的,除了创建一个公共领域之外还有什么不同?
public class Book
{
public string Title;
}
Run Code Online (Sandbox Code Playgroud) 在我看过的大部分代码中(在SO上,我都会在我自己的代码中使用codeproject.com),我已经看到为一个类包含的每个私有字段创建公共属性,即使它们是最多的基本类型get; set;:
private int myInt;
public int MyInt
{
get { return myInt; }
set { myInt = value }
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:这与以下方面有何不同:
public int MyInt;
Run Code Online (Sandbox Code Playgroud)
如果我们应该使用属性而不是公共字段,为什么我们应该在这种特定情况下使用它们呢?(我不是在讨论更复杂的例子,其中getter和setter实际上做了一些特殊的事情,或者只有一个get或set(只读/写)而不是只返回/设置私有字段的值).它似乎没有添加任何额外的封装,只在IntelliSense中提供一个漂亮的图标,并放在类图中的特殊部分!
每当有关于Properties的可信度的问题时,我发现大多数讨论都是围绕函数/方法和属性进行的.但我也想知道使用属性与相关私有字段直接与公共字段直接使用的令人信服的理由,包含最常见的获取/设置行为而没有其他处理,我的意思是这种方式
public string CustomerName;
Run Code Online (Sandbox Code Playgroud)
VS
private string customerName;
public string CustomerName
{
get{return customerName;}
set(string value){this.customerName=value;}
}
Run Code Online (Sandbox Code Playgroud) 没有(显式)引用firstName应该隐藏的firstName私有变量.你能解释一下这是怎么回事吗?我假设有一些私有变量被getted和setted.谢谢.
// auto-implemented property FirstName
public string FirstName { get; set; }
Run Code Online (Sandbox Code Playgroud) 我知道在C#中,您可以轻松地创建数据类型的访问器,例如,通过执行以下操作:
public class DCCProbeData
{
public float _linearActual { get; set; }
public float _rotaryActual { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
但是我的同事建议我这样做:
public class DCCProbeData
{
private float _linearActual = 0f;
public float LinearActual
{
get { return _linearActual; }
set { _linearActual = value; }
}
private float _rotaryActual = 0f;
public float RotaryActual
{
get { return _rotaryActual; }
set { _rotaryActual = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
我的方式似乎更简单,更简洁.无论采用哪种方式,有什么区别和好处?
谢谢
编辑只是一个注释,我的同事能够使用图表文件中最容易找到的"类详细信息"窗格中的"重构"选项生成"第二种方式"的代码.这样可以轻松添加许多属性,而无需手动创建访问器.
我有使用自动实现的属性的简单类:
Public Class foo
{
public foo() { }
public string BarName {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我显然在我的类中使用变量BarName,现在需要在设置属性值时添加逻辑(它必须全部为大写,如图).这是否意味着我现在需要为BarName创建一个私有变量,例如_BarName,并将我的类中使用的当前BarName变量更改为_BarName?
Public Class foo
{
public foo() {}
private string _BarName = "";
public string BarName
{
get {return _BarName;}
set {_BarName = Value.ToString().ToUpper();}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在努力确保我理解使用自动实现的属性的含义,以及当我/如果我需要更改某些内容时它会带来什么.我假设重构,如上所示,不是一个突破性的变化,因为该属性基本上保持不变; 它只是在课堂上做了一些工作,以保持这种方式并添加所需的逻辑.
另一个可能更有意义的例子是我需要在使用setter或getter时调用某个方法; 更多然后改变价值.
这似乎是设置属性的代码行和行的公平交易.