我对理解属性和变量感到困惑
public class ABC()
{
public int A;
public int B { get; set; }
}
A和B之间的确切区别是什么?
答案 0 :(得分:57)
正如许多人所指出的,A是字段,B是属性。
真正的问题是,你为什么要关心,以及使用什么?
我指的是blog post of Jonathan Aneja:
(它在VB中,但它也适用于C#;))
那么为什么要在字段上使用属性,原因有以下几点:
1。字段不能在接口
中使用你不能强制执行a 对象的公共合同中的字段 通过界面。对于物业 虽然它运作良好。
2。验证
虽然您的申请目前可能 不需要任何验证逻辑 设定一个特定的值,改变 业务要求可能需要 稍后插入此逻辑。在那 将字段更改为属性 是消费者的一个突破性变化 你的API。 (例如,如果有人 通过反思检查你的班级。
3。二进制序列化
将字段更改为属性是a 如果您使用二进制文件,则会发生变化 序列化。顺便说一下,这是 VB10的原因之一 自动实现的属性有一个 “可绑定”的支持领域(即你可以 表示支持字段的名称 在代码中) - 这样,如果你改变了 自动实现的属性 扩大财产,你仍然可以 保持序列化兼容性 通过保持支持字段名称 同样(在C#中你被迫改变它 因为它会生成支持字段 有无法辨认的名字。)
4。许多.NET数据绑定基础结构绑定到属性但不绑定字段
我听说过双方的争论 这是否是一件好事, 但现实是它的方式 现在正常工作。 (请注意:WPF绑定适用于属性)
5。公开字段是FxCop violation
由于上面列出的许多原因 :)
可能有更多原因。
我还想指出一个blog post of Jeff Atwood,最后引用它:
这里带走的重要一点是避免编写无关紧要的代码。公共变量的属性包装器是无意义代码的本质。
答案 1 :(得分:20)
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;
}
}
请注意,这种转换适用于所有C#属性 - 对ABC.B的访问将转换为方法调用。属性基本上提供了“变量”的错觉,而实际上只是一对巧妙伪装的方法。
这很重要,因为它允许您声明自己的 get和set方法体,它可以验证值或做其他有趣的事情:
private int b;
public int B {
get { return b; }
set {
if (value < 0) throw new ArgumentOutOfRangeException("value");
b = value;
}
}
请注意,大多数属性都会使用字段来存储其值。除了字段之外,属性本身很少存在。
答案 2 :(得分:4)
属性是一种短的getter和/或setter。您可以向属性的set
或get
添加逻辑或将其设置为私有,这意味着无法从外部访问它们,其中变量始终可访问(如果它是公共的)。 / p>
答案 3 :(得分:4)
在C#any&#34;变量&#34;具有getter和setter的东西被称为属性。变量没有getter和setter,所以这就是教科书所说的。
我的编程讲师让我们为几乎所有用Java创建的变量都有getter和setter。即使是索引变量,如果它们在全局类范围内声明,他也会使用getter和setter。我认为这可能是矫枉过正,但它确实让我做了吸气鬼和制定者。
关于getter和setter的真实之处在于它们不仅可以设置内部变量。大多数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; }
以上是编写以下内容的简便方法
private string firstName;
public string FirstName
{
get
{
//...code here
}
set
{
//...code here
}
}
答案 4 :(得分:3)
变量是一个变量。
属性是一种特殊类型的方法,可以公开该变量。因此,因为它是一种方法,除了暴露变量之外,你还可以做其他一些事情。
来自MSDN:
Property语句引入了属性的声明。属性可以具有Get过程(只读),Set过程(只写)或两者(读写)。使用自动实现的属性时,可以省略Get和Set过程。有关更多信息,请参见自动实现的属性(Visual Basic)。
您只能在班级使用Property。这意味着属性的声明上下文必须是类,结构,模块或接口,并且不能是源文件,命名空间,过程或块。有关更多信息,请参阅声明上下文和默认访问级别。
默认情况下,属性使用公共访问权限。您可以使用Property语句上的访问修饰符调整属性的访问级别,并且可以选择将其中一个属性过程调整为限制性更强的访问级别。
答案 5 :(得分:0)
在您的示例中,A
是类ABC
上的公共字段,B
是类ABC
上的公共属性。具体而言,B
是auto-implemented property。这意味着“引擎盖下”编译器会为您完成一些工作,并有效地将您的代码转换为:
public class ABC()
{
private int b;
public int A;
public int B
{
get
{
return b;
}
set
{
b = value;
}
}
}
答案 6 :(得分:0)
变量的定义基本上是根据分配给这些变量的修饰符从类或同一类访问值。
当我们定义一个属性时,会为单个属性创建两个方法,因此会产生额外的开销,这是属性的缺点。
属性的优点是将值或值设置为类的私有变量。
答案 7 :(得分:0)
有一篇很好的文章(下面的链接),关于使用Microsoft本身的字段/变量与属性。尽管该文章实质上讨论了FxCop违反规则,但它清楚地定义了两者之间的区别以及确切的使用准则。
文章摘录:
字段的主要用途应作为实现细节。 字段应为私有字段或内部字段,并应通过使用 属性。访问属性就像访问字段一样容易,并且 属性访问器中的代码可以随类型的功能而改变 扩展而不会引入重大更改。
参考: https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-3.0/ms182141(v=vs.80)