到现在为止,我对Properties
&的印象是Methods
C#中的两件事。但是后来我做了下面的事情。
这对我来说是个“开眼神”。我期待一种属性stringProp
和一种方法,stringProp
但是我得到了。
为什么会这样?有人可以解释一下。
到现在为止,我对Properties
&的印象是Methods
C#中的两件事。但是后来我做了下面的事情。
这对我来说是个“开眼神”。我期待一种属性stringProp
和一种方法,stringProp
但是我得到了。
为什么会这样?有人可以解释一下。
stringProp = stringProp();
将无法编译(stringProp is a 'property' but is used like a 'method'
)
Answers:
是的,编译器会为属性生成一对get和set方法,并为自动实现的属性生成一个私有支持字段。
public int Age {get; set;}
等于:
private int <Age>k__BackingField;
public int get_Age()
{
return <Age>k__BackingField;
}
public void set_Age(int age)
{
<Age>k__BackingField = age;
}
访问您的属性的代码将被编译为调用这两种方法之一。这正是将公共场所更改为公共财产的重大原因之一。
请参阅Jon Skeet的“为何重要”。
<Age>k__BackingField
是该字段的名称。即使在C#中这是一个非法名称,在IL(中间语言)中也是一个完全有效的名称。这是为声明该字段而生成的IL :.field private int32 '<Age>k__BackingField'
。大多数编译器生成的类型(例如lambda闭包和枚举器)都包含<>
在名称中。
严格地说,属性不是方法,虽然他们都确实由getter和setter方法(也称为存取)的支持。当您编写这样的代码时(前提是您修改代码以消除下面提到的编译错误)
myFoo.stringProp = "bar";
编译器实际上会生成如下的IL代码:
ldstr "bar"
callvirt foo.set_stringProp
set_stringProp
该属性的设置方法在哪里。实际上,如果您愿意,可以直接通过反射调用这些方法。
但是,您发布的代码示例在Visual Studio的intellisense中可能还不错,但无法编译。尝试构建项目,您将看到类似以下的错误:
类型“ foo”已经包含“ stringProp”的定义
这是Visual Studio的智能问题,按名称选择。顺便说一下,由于相同类型的名称冲突,您的代码甚至无法编译。
但是您是对的,属性是最后的方法:
public class A {
public string Name {get;set;}
}
这里的Name
属性转换为2种方法:get_Name()
和set_Name()
。
实际上,如果您这样定义类:
public class A {
public string Name {get;set;}
public string get_Name() {
return "aaa";
}
}
您将得到编译错误,因为已经定义get_Name
(属性)
是。属性是mutator
方法。
在计算机科学中,变异器方法是一种用于控制变量更改的方法。它们也被广泛称为二传手方法。通常,setter会伴随有getter(也称为访问器),该方法返回私有成员变量的值。
遵循封装原理,mutator方法最常用于面向对象的编程中。根据此原理,将类的成员变量设为私有,以隐藏它们并保护它们免受其他代码的侵害,并且只能通过将所需的新值作为参数的公共成员函数(mutator方法)进行修改,并可选地进行验证并修改私有成员变量。
突变方法也可以在非面向对象的环境中使用。在这种情况下,对要修改的变量的引用将与新值一起传递到mutator。在这种情况下,编译器无法限制代码绕过mutator方法并直接更改变量。开发人员有责任确保仅通过mutator方法修改变量,而不能直接修改变量。
在支持它们的编程语言中,属性提供了一种便捷的选择,而不会放弃封装的效用。