C#属性实际上是方法吗?


77

到现在为止,我对Properties&的印象是MethodsC#中的两件事。但是后来我做了下面的事情。

在此处输入图片说明

这对我来说是个“开眼神”。我期待一种属性stringProp和一种方法,stringProp但是我得到了。

为什么会这样?有人可以解释一下。


4
目前还不清楚您在寻找什么作为答案。但Properties表示:“ ...实际上,它们是称为访问器的特殊方法。”
Damien_The_Unbeliever 2014年


30
具有相同名称的属性和方法是不合法的,因此我并不感到Intellisense感到困惑。
Mike Zboray 2014年

那是不合法的尝试stringProp = stringProp();将无法编译(stringProp is a 'property' but is used like a 'method'
Alex

请注意,在我看来,使您的眼睛“张开”的是工具中的一个问题,该问题将两个成员显示为“过载”。方法名称无关的地方。访问器方法与属性的名称不同。
Iravanchi 2014年

Answers:


113

是的,编译器会为属性生成一对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的“为何重要”


30
@ dc7a9163d9实际上,<Age>k__BackingField是该字段的名称。即使在C#中这是一个非法名称,在IL(中间语言)中也是一个完全有效的名称。这是为声明该字段而生成的IL :.field private int32 '<Age>k__BackingField'。大多数编译器生成的类型(例如lambda闭包和枚举器)都包含<>在名称中。
dcastro 2014年

我有一个既可以执行SET又可以执行GET的方法。如果我能像没有()一样叫它,那就太好了
Herman Van Der Blom19年

24

严格地说,属性不是方法,虽然他们确实由getter和setter方法(也称为存取)的支持。当您编写这样的代码时(前提是您修改代码以消除下面提到的编译错误)

myFoo.stringProp = "bar";

编译器实际上会生成如下的IL代码:

ldstr       "bar"
callvirt    foo.set_stringProp

set_stringProp该属性的设置方法在哪里。实际上,如果您愿意,可以直接通过反射调用这些方法。

但是,您发布的代码示例在Visual Studio的intellisense中可能还不错,但无法编译。尝试构建项目,您将看到类似以下的错误:

类型“ foo”已经包含“ stringProp”的定义


2
最大的区别是属性可以通过属性附加其他关联的元数据,这些属性可能不适用于方法。
丹·布莱恩特

18

这是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(属性)


-2

是。属性是mutator方法。

在计算机科学中,变异器方法是一种用于控制变量更改的方法。它们也被广泛称为二传手方法。通常,setter会伴随有getter(也称为访问器),该方法返回私有成员变量的值。

遵循封装原理,mutator方法最常用于面向对象的编程中。根据此原理,将类的成员变量设为私有,以隐藏它们并保护它们免受其他代码的侵害,并且只能通过将所需的新值作为参数的公共成员函数(mutator方法)进行修改,并可选地进行验证并修改私有成员变量。

突变方法也可以在非面向对象的环境中使用。在这种情况下,对要修改的变量的引用将与新值一起传递到mutator。在这种情况下,编译器无法限制代码绕过mutator方法并直接更改变量。开发人员有责任确保仅通过mutator方法修改变量,而不能直接修改变量。

在支持它们的编程语言中,属性提供了一种便捷的选择,而不会放弃封装的效用。

参考:http : //en.wikipedia.org/wiki/Mutator_method

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.