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

发布于 2024-08-01 15:28:19 字数 397 浏览 2 评论 0原文

我正在检查.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的私有变量名称是什么? 互联网上的教程说编译器会自动创建一个私有变量。那么如果我想在此类的方法中使用它,我该如何使用/访问私有变量呢?

I was checking the new features of .NET 3.5 and found that in C# 3.0, we can use

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

instead of

private string name;

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

If i use the Automatic Properties,what will be the private variable name for Name ? the tutorials on internet says that compiler will automatically create a private variable.So how can i use /access the private variable,if i want to use it in a method in this class ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

回忆躺在深渊里 2024-08-08 15:28:19

重写得更清晰

该字段生成正常,但它作为常规字段对您的代码不可见。

这是典型的自动属性:

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

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

Rewritten to be more clear

The field is generated alright, but it is not visible to your code as a regular field.

Here's your typical automatic property:

public string FirstName  { get; set; }

which, if we look at the compiled assembly, produces this backing store field:

[CompilerGenerated]
private string <FirstName>k__BackingField;

Note the < and > in there, which are not characters you can use in your own field names. Nor can you access that field, because it doesn't "exist" as far as the compiler cares, when it looks at your code.

The real question here, from me, is why you would want to access that field. In other words, why do you need access to the field, and what does it do for your code that accessing the property don't do?

If you want to prevent outside write-access to the field, that's easily doable by making the setter method private, like this:

public string FirstName  { get; private set; }

Note that since the field is actually present in the assembly, it means that this is not JITter magic, but compiler magic, and thus you could use reflection to find, and access, that field.

But again, why would you want to?

Now, let's assume that there really is a legitimate reason for you wanting to use the field, instead of the property. I can think of one, though I would probably do it differently, and that would be that you want to pass the field name to a method as an out or ref parameter, like this:

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

You can't pass properties as out/ref-parameters, so this code won't work:

AdjustName(ref string FirstName);

In this case, you need to fall back to the "old" way of defining properties, adding the backing store field manually, like this:

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

With this in place, you can call that method:

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

However, I would probably change that method in order to return the new value, instead of directly adjusting a referenced variable.

翻了热茶 2024-08-08 15:28:19

正如已经说过的:您无法访问自动生成的变量(不使用糟糕的技巧)。 但我假设你问这个问题是因为你只想有一个吸气剂,但仍然想使用自动属性......对吗? 在这种情况下,您可以使用这个:

public string FirstName  { get; private set; }

现在您有一个私有 setter 和一个公共 getter。

As already said: You cannot access the automatically generated variable (without using bad tricks). But I assume you are asking that question because you want to have only a getter, but still want to use automatic properties ... right? In that case you can use this one:

public string FirstName  { get; private set; }

Now you have a private setter and a public getter.

我的痛♀有谁懂 2024-08-08 15:28:19

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

If you use automatic properties, then you cannot access the private field. It is not only private, it is also anonymous.

辞慾 2024-08-08 15:28:19

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

在源代码中,如果您在 person 类中编写代码,则只需要且仅允许使用属性访问器 person.LastNameLastName

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

So how can i use /access the private variable,if i want to use it in a method in this class ?

In your source code you only need to, and are only allowed to work with the Property Accessor person.LastName or LastName if you are writing code inside the person class.

The compiler will automatically create a private member variable, or backing field, but this exists in the CIL code. It does not exist anywhere in your source code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文