我对理解属性和变量感到困惑
public class ABC()
{
public int A;
public int B { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
A和B之间的确切区别是什么?
Arc*_*rus 63
正如许多人所指出的,A是一个领域,B是一个属性.
真正的问题是,你为什么要关心,以及使用什么?
我参考Jonathan Aneja的博客文章:
(它在VB中,但它也适用于C#;))
那么为什么在字段上使用属性,有5个原因:
1.字段不能在接口中使用
您不能通过接口强制在对象的公共合同中存在字段.对于属性虽然它工作正常.
2.验证
虽然您的应用程序当前可能不需要任何验证逻辑来设置特定值,但更改业务需求可能需要稍后插入此逻辑.此时,将字段更改为属性是API的消费者的重大变化.(例如,如果有人通过反思检查你的班级).
3.二进制序列化
如果您使用二进制序列化,则将字段更改为属性是一个重大变化.顺便说一下,这是VB10自动实现的属性具有"可绑定"支持字段的原因之一(即,您可以在代码中表示支持字段的名称) - 这样,如果您将自动实现的属性更改为扩展属性,您仍然可以通过保持支持字段名称相同来维护序列化兼容性(在C#中,您必须更改它,因为它会生成具有不可绑定名称的支持字段).
4.许多.NET数据绑定基础结构绑定到属性而不绑定字段
我听到双方都争论这是否是一件好事,但现实是它现在的运作方式.(请注意:WPF绑定适用于属性)
5.暴露公共字段是违反FxCop的行为
由于上面列出的许多原因:)
可能有更多原因.
我还想指出Jeff Atwood的博客文章,最后引用它:
在这里拿走非常重要的是避免编写无关紧要的代码.围绕公共变量的属性包装器是无意义代码的本质.
cdh*_*wie 21
A是字段,B是属性.一个属性基本上是getter和setter的语法糖.您定义的类将编译为以下内容:
public class ABC()
{
public int A;
private int backing_B;
public void set_B(int value)
{
backing_B = value;
}
public int get_B()
{
return backing_B;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这种转换适用于所有C#属性 - 对ABC.B的访问将转换为方法调用.属性基本上提供了"变量"的错觉,而实际上只是一对巧妙伪装的方法.
这很重要,因为它允许您声明自己的 get和set方法体,它可以验证值或执行其他有趣的事情:
private int b;
public int B {
get { return b; }
set {
if (value < 0) throw new ArgumentOutOfRangeException("value");
b = value;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,大多数属性将使用字段来存储其值.除了字段之外,属性本身很少存在.
小智 5
在 C# 中,任何具有 getter 和 setter 的“变量”都称为属性。变量没有 getter 和 setter,教科书上就是这么说的。
我的编程老师为我们在 Java 中创建的几乎每个变量都设置了 getter 和 setter。即使是索引变量,如果它们是在全局类范围内声明的,他也让我们使用 getter 和 setter。我认为这可能有点矫枉过正,但它确实让我制作了 getter 和 setter。
getter 和 setter 的真正作用在于,它们很可能不仅仅只是设置内部变量。大多数设置器将执行某种类型的数据验证,以确保可以将数据设置为变量。getter 还可能检查返回数据的某些条件。
如果您的属性是私有的,并且您的 setter 和 getter 是公共的,那么从技术上讲,任何人都可以访问您的变量并更改它,就像他们可以公开访问实际变量一样。因此,实际上,您应该检查数据以确保其有效或进行其他数据检查。
private int myVariable;
public int myVariable
{
get
{
return myVariable;
}
set
{
if (value < 0)
{
throw new Exception("This is your exception some where else in code");
}
myVariable = value; //remember value is something that is
//declared automatically
}
}
public string FirstName { get; set; }
Run Code Online (Sandbox Code Playgroud)
上面是下面的简写方式
private string firstName;
public string FirstName
{
get
{
//...code here
}
set
{
//...code here
}
}
Run Code Online (Sandbox Code Playgroud)