代码之家  ›  专栏  ›  技术社区  ›  Shyju

C 3.0:自动属性-编译器创建的私有变量的名称是什么?

  •  8
  • Shyju  · 技术社区  · 16 年前

    我检查了.NET 3.5的新功能,发现在C 3.0中,我们可以使用

    public class Person 
    {    
     public string FirstName  { get; set; }
     public string LastName  { get; set; }
    }
    

    而不是

    private string name;
    
    public string Name
    {
      get { return name; }
      set { name = value; }
    }
    

    如果使用自动属性,名称的私有变量名是什么?因特网上的教程说编译器会自动创建一个私有变量,所以如果我想在这个类的方法中使用这个私有变量,我该如何使用/访问它呢?

    4 回复  |  直到 14 年前
        1
  •  18
  •   Community Mohan Dere    14 年前

    重写得更清楚

    该字段是正常生成的,但对于代码来说,它是不可见的常规字段。

    以下是您的典型自动属性:

    public string FirstName  { get; set; }
    

    如果我们查看已编译的程序集,它将生成此后备存储字段:

    [CompilerGenerated]
    private string <FirstName>k__BackingField;
    

    请注意其中的<和>不是您可以在自己的字段名中使用的字符。也不能访问该字段,因为在编译器关心的范围内,当它查看您的代码时,它并不“存在”。

    我的真正问题是 为什么? 您将要访问该字段。换句话说,为什么您需要访问该字段,以及它对您的代码做了什么而访问该属性却不做?

    如果要防止对字段的外部写访问,可以通过将setter方法设为私有方法来轻松实现,如下所示:

    public string FirstName  { get; private set; }
    

    注意,由于字段实际上存在于程序集中,这意味着这不是抖动魔术,而是编译器魔术,因此您可以使用反射来查找和访问该字段。

    但是,你为什么要这么做?

    现在,假设您确实有一个合理的理由想要使用字段而不是属性。我可以想到一个方法,尽管我可能会做得不同,那就是您希望将字段名作为out或ref参数传递给一个方法,如下所示:

    public void AdjustName(ref String name)
    {
        name = Capitalize(name);
    }
    

    不能将属性作为out/ref参数传递,因此此代码将不起作用:

    AdjustName(ref string FirstName);
    

    在这种情况下,您需要回到定义属性的“旧”方法,手动添加backing store字段,如下所示:

    private string firstName;
    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }
    

    有了它,您可以调用该方法:

    AdjustName(ref string firstName); // note the field, not the property
    

    但是,我可能会更改该方法以返回新值,而不是直接调整引用变量。

        2
  •  4
  •   Achim    16 年前

    如前所述:您不能访问自动生成的变量(不使用坏技巧)。但是我假设你问这个问题是因为你只想有一个getter,但是仍然想使用自动属性…正确的?在这种情况下,您可以使用这个:

    public string FirstName  { get; private set; }
    

    现在你有了一个私人设置者和一个公共获取者。

        3
  •  1
  •   John Saunders    16 年前

    如果使用自动属性,则无法访问私有字段。它不仅是私有的,而且是匿名的。

        4
  •  0
  •   Saajid Ismail    16 年前

    那么,如果我想在这个类的方法中使用私有变量,我如何使用/访问它呢?

    在源代码中,您只需要,并且只允许使用属性访问器 person.LastName LastName 如果您在Person类中编写代码。

    编译器将自动创建一个私有成员变量或支持字段,但它存在于 CIL 代码。它在源代码中的任何地方都不存在。

    推荐文章