10

我在检查 .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; }
}

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

4

4 回答 4

21

重写得更清楚

该字段生成正常,但您的代码看不到它作为常规字段。

这是您典型的自动属性:

public string FirstName  { get; set; }

如果我们查看已编译的程序集,则会生成以下后备存储字段:

[CompilerGenerated]
private string <FirstName>k__BackingField;

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

对我来说,真正的问题是你为什么要访问该字段。换句话说,为什么您需要访问该字段,它对您的代码有什么作用而访问该属性却没有呢?

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

public string FirstName  { get; private set; }

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

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

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

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

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

AdjustName(ref string FirstName);

在这种情况下,您需要退回到定义属性的“旧”方式,手动添加后备存储字段,如下所示:

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

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

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

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

于 2009-08-14T10:00:17.937 回答
5

如前所述:您无法访问自动生成的变量(不使用坏技巧)。但是我假设您问这个问题是因为您只想拥有一个吸气剂,但仍想使用自动属性……对吗?在这种情况下,您可以使用这个:

public string FirstName  { get; private set; }

现在你有了一个私有的 setter 和一个公共的 getter。

于 2009-08-14T10:09:24.660 回答
1

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

于 2009-08-14T09:59:00.560 回答
0

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

在您的源代码中,您只需要并且只允许使用 Property Accessorperson.LastName或者LastName如果您在 person 类中编写代码。

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

于 2009-08-14T10:12:18.180 回答