我对于理解属性(property)和变量(variable)有些疑惑。
public class ABC()
{
public int A;
public int B { get; set; }
}
在A和B之间的确切区别是什么?
我对于理解属性(property)和变量(variable)有些疑惑。
public class ABC()
{
public int A;
public int B { get; set; }
}
在A和B之间的确切区别是什么?
正如许多人指出的那样,A是一个“字段”,B是一个“属性”。
真正的问题是,你为什么要在意,以及该使用什么?
我参考了Jonathan Aneja的博客文章:
(虽然它是用VB写的,但同样适用于C# ;))
那么为什么要使用属性而不是字段,有5个原因:
通过接口无法强制要求对象的公共协定中存在一个字段,但对于属性则没有问题。
尽管您的应用程序目前可能不需要任何验证逻辑来设置特定值,但更改业务需求可能需要稍后插入此逻辑。此时,将字段更改为属性会破坏 API 的消费者(例如,如果有人通过反射检查您的类)。
如果您正在使用二进制序列化,则将字段更改为属性会破坏兼容性。顺便说一句,这是 VB10 的自动实现属性具有“可绑定”后备字段(即,您可以在代码中表达后备字段的名称)的原因之一 - 这样,如果您将自动实现属性更改为扩展属性,则仍然可以通过保持后备字段名称相同来保持序列化兼容性(在 C# 中,您被迫更改它,因为它生成具有不可绑定名称的后备字段)。
我听到过对于是否这样做是好事的争论,但现实情况是它现在就是这样。 (来自我的注释:WPF 绑定适用于属性)
由于上述原因,这是不允许的。
可能还有更多的原因。
我也想指向Jeff Atwood的博客文章,并用其中的一句话作为结论:
这里真正重要的是避免编写无关紧要的代码。而在公共变量周围添加属性包装器就是毫无意义的代码精髓。
public string Name {get;set;}
,该怎么办呢?为什么我们要这样做,而不是只使用 public Name String;
?我在多个地方看到过这种情况,但我无法理解,除了“公开字段是不好的实践”之外,还有什么其他原因使用它。在我看来,这两者之间没有区别。 - CutePoisonA是一个字段,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的访问将被转换为方法调用。属性基本上提供了一个"变量"的假象,实际上只是一对巧妙伪装的方法。private int b;
public int B {
get { return b; }
set {
if (value < 0) throw new ArgumentOutOfRangeException("value");
b = value;
}
}
请注意,大多数属性将使用字段存储其值。 除了字段,属性很少存在于自己的情况下。
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
}
}
属性是一种简短的getter或setter。您可以向属性的set
或get
添加逻辑,或使它们成为私有的,这意味着它们不能从外部访问,而变量始终可以访问(如果它是公共的)。
变量是一个可变的值。
属性是一种特殊类型的方法,可以公开访问该变量。由于它是一个方法,因此您可以在其中执行除了公开变量之外的其他操作。
根据MSDN:
Property语句引入属性声明。属性可以具有 Get 过程(只读)、Set 过程(只写)或两者兼备(读/写)。使用自动实现的属性时,可以省略 Get 和 Set 过程。有关详细信息,请参阅 自动实现属性 (Visual Basic)。
您只能在类级别上使用Property。这意味着属性的声明上下文必须是类、结构、模块或接口,不能是源文件、命名空间、过程或块。有关详细信息,请参阅 声明上下文和默认访问级别。
默认情况下,属性使用公共访问级别。可以在 Property 语句上使用访问修饰符来调整属性的访问级别,并且还可以选择将其属性过程之一调整为更严格的访问级别。
微软官方有一篇非常好的文章(链接如下),讲述了使用字段/变量与属性之间的区别。虽然这篇文章主要是讨论FxCop违规规则,但它清晰地定义了两者之间的区别和确切的使用指南。
以下是该文章的摘录:
字段的主要用途应该是作为实现细节。字段应该是私有或内部的,并且应该使用属性来公开。访问属性就像访问字段一样容易,而属性访问器中的代码可以随着类型特性的扩展而更改,而不会引入破坏性的更改。
Refer: https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-3.0/ms182141(v=vs.80)
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;
}
}
}
变量基本上是为了从类中访问值或根据分配给这些变量的修饰符进入同一类中而定义的。
当我们定义属性时,会为单个属性创建两种方法,因此会产生额外的开销,这是属性的缺点。
属性的优点是可以获取或设置类的私有变量的值。