什么是C#中的属性和variables之间的区别
我对理解属性和variables有困惑
public class ABC() { public int A; public int B { get; set; } }
A和B之间的确切区别是什么?
谢谢。
正如很多人所指出的,A是一个领域 ,B是一个财产 。
真正的问题是,你为什么要关心,以及使用什么?
我指的是Jonathan Aneja的博客文章 :
(它在VB中,但它也适用于C#;))
那么为什么要在字段上使用属性,原因有五:
1.字段不能在接口中使用
你不能通过一个接口强制对象的公共契约中存在一个字段。 对于属性,虽然它工作正常。
2.validation
尽pipe当前您的应用程序可能不需要任何validation逻辑来设置特定值,但更改业务需求可能需要稍后插入此逻辑。 在这一点上,将字段更改为属性对于API的消费者来说是一个重大改变。 (例如,如果有人正在通过反思来检查你的课程)。
3.二进制序列化
如果您使用二进制序列化,将字段更改为属性是一个重大改变。 顺便说一句,这是VB10的自动实现的属性有一个“可绑定的”支持字段的原因之一(即您可以在代码中表示支持字段的名称) – 这样,如果您将自动实现的属性更改为扩展的属性,仍然可以通过保持后台字段名称相同来保持序列化兼容性(在C#中,您不得不更改它,因为它会生成具有不可绑定名称的后备字段)。
4.很多.NET数据绑定基础设施绑定到属性,但不是字段
我听到双方都认为这是好事,但实际情况是现在这样。 (请注意,WPF绑定对属性起作用)
暴露公共领域是FxCop违规
对于上面列出的许多原因:)
可能有更多的原因。
我还想指出杰夫·阿特伍德的博客文章,并从中引用一句话:
在这里拿走真正重要的是避免编写无关紧要的代码。 公有variables的属性包装是无意义代码的本质。
A是一个字段,B是一个属性。 一个属性基本上是用于吸气和定火者的语法糖。 你定义的类将被编译成如下所示:
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的访问将被转换为方法调用。 属性基本上提供了一个“variables”的幻觉,而实际上只是一个巧妙的变相的方法。
这很重要,因为它允许你声明你自己的 get和set方法体,它可以validation值或做其他有趣的事情:
private int b; public int B { get { return b; } set { if (value < 0) throw new ArgumentOutOfRangeException("value"); b = value; } }
请注意,大多数属性将使用一个字段来存储它们的值。 除了田地,物业自己很less存在。
一个物业是一个短的吸气和/或二传手。 您可以添加逻辑到set
或get
属性,或者使其成为私有的,这意味着它们不能从外部访问,而variables总是可访问的(如果是公共的)。
variables就是variables。
属性是暴露该variables的一种特殊types的方法。 因为这是一种方法,所以除了暴露variables之外,还可以做其他一些事情。
来自MSDN:
财产声明介绍了财产的声明。 一个属性可以有一个Get过程(只读),一个Set过程(只写)或两者(读写)。 使用自动实现的属性时,可以省略“获取并设置”过程。 有关更多信息,请参阅自动实现的属性(Visual Basic)。
您只能在课堂上使用Property。 这意味着属性的声明上下文必须是类,结构,模块或接口,并且不能是源文件,名称空间,过程或块。 有关更多信息,请参阅声明上下文和默认访问级别。
默认情况下,属性使用公共访问。 您可以使用Property语句上的访问修饰符来调整属性的访问级别,并且可以select将其属性过程之一调整为更具限制性的访问级别。
在C#中,任何具有getter和setter的“variables”都被称为属性。 一个variables没有getter和setter,所以这是课本上说的。
我的程序devise教师让我们几乎每个在Java中创build的variables都有getter和setter。 即使索引variables,他让我们使用一个getter和setter,如果他们被声明在全局类作用域。 我认为这可能是矫枉过正,但它确实让我做了吸气和安装人员。
关于getter和setter的真实情况是,他们不仅仅是设置一个内部variables。 大多数设置人员将执行某种types的数据validation,以确定可以将数据设置为variables。 吸气剂也可能检查返回的数据是否符合某些标准。
如果你的财产是私人的,你的设置者和获取者在技术上是公开的,任何人都可以访问你的variables,并将其改变,就好像他们可以公开访问实际variables一样。 所以,实际上,你应该检查你的数据,以确定它是有效的或其他数据检查。
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 } }
在你的例子中, A
是类ABC
上的公共字段, B
是类ABC
上的公共属性。 具体来说, B
是一个自动实现的属性 。 这意味着“底层”编译器会为您做一些工作,并有效地将您的代码转换为:
public class ABC() { private int b; public int A; public int B { get { return b; } set { b = value; } } }
variables的定义基本上是为了从一个类中访问值,或者根据赋值给这些variables的修饰符将它们放入同一个类中。
当我们为一个属性定义一个属性时,会为单个属性创build两个方法,所以会产生额外的开销,这是属性的缺点。
属性的优点是把值或私有variables赋值给类。
你可以设置只读的属性,只声明获取属性fnc。 但是我们不能用variables来这样做。
–BinhPT–