【问题标题】:Are C# properties actually Methods?C# 属性实际上是方法吗?
【发布时间】:2014-05-30 22:11:07
【问题描述】:

到目前为止,我的印象是 PropertiesMethods 在 C# 中是两个不同的东西。但后来我做了类似下面的事情。

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

为什么会这样?谁能解释一下。

【问题讨论】:

  • 目前还不清楚您要寻找什么作为答案。但是Properties 说:“......它们实际上是称为访问器的特殊方法。”
  • 拥有同名的属性和方法是不合法的,所以我并不奇怪 Intellisense 会感到困惑。
  • 这是不合法的并且尝试stringProp = stringProp();不会编译(stringProp is a 'property' but is used like a 'method'
  • 请注意,在我看来,让您“睁大眼睛”的是工具中的一个问题,它将两个成员显示为“过载”;其中方法的名称不相关。访问器方法与属性的名称不同。

标签: c# .net oop


【解决方案1】:

是的,编译器会为一个属性生成一对 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 的 Why Properties Matter

【讨论】:

  • @dc7a9163d9 实际上,&lt;Age&gt;k__BackingField 是该字段的名称。尽管这在 C# 中是一个非法名称,但它在 IL(中间语言)中是一个完全有效的名称。这是为声明该字段而生成的 IL:.field private int32 '&lt;Age&gt;k__BackingField'。大多数编译器生成的类型,例如 lambda 闭包和枚举器的名称中都包含 &lt;&gt;
  • 我有一种方法可以同时执行 SET 和 GET。如果我可以将其称为属性,而无需 (),那就太好了
【解决方案2】:

严格来说,属性不是方法,尽管它们确实受到 getter 和 setter 方法(也称为访问器)的支持。当你写这样的代码时(前提是你修改了代码以消除下面提到的编译错误)

myFoo.stringProp = "bar";

编译器实际上会生成这样的 IL 代码:

ldstr       "bar"
callvirt    foo.set_stringProp

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

但是,您发布的代码示例在 Visual Studio 的智能感知中可能看起来不错,但无法编译。尝试构建项目,您将看到如下错误:

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

【讨论】:

  • 最大的区别是属性可以通过属性有额外的关联元数据,这些元数据可能不适用于方法。
【解决方案3】:

这是视觉工作室情报问题,按名称选择。顺便说一句,由于同一类型的名称冲突,您的代码甚至无法编译。

但你是对的,属性最后的方法:

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

【讨论】:

    【解决方案4】:

    是的。属性是mutator 方法。

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

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

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

    在支持它们的编程语言中,属性提供了一种方便的替代方案,而不会放弃封装的实用性。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-07
      • 2021-12-17
      • 1970-01-01
      • 2011-01-13
      相关资源
      最近更新 更多