我们是否允许在自动实现属性的情况下创建私有变量?

本文关键字:创建 情况下 变量 属性 实现 是否 我们 | 更新日期: 2023-09-27 17:55:04

假设我们使用自动实现的属性。

的例子:

public class Test {
    public int val1 { get; set; }
}

以上代码自动生成一个私有变量:private int val1

我的问题是,如果我们显式地在自动实现的属性代码上面声明这个变量会发生什么?

的例子:

public class Test {
   private int val1;
   public int val1 { get; set; }
}

两个例子是否相等?

我们是否允许在自动实现属性的情况下创建私有变量?

编译器创建的后备字段不命名为val1。这个变量的名字是以一种不可能打断你代码的方式创建的,所以你不应该担心这个。

支持字段名的生成方式在c#中是不正确的标识符,但在CLR规范中是可以的。这就是为什么它永远不会打断你的代码。

这就是为什么下面的代码编译得很好:

class Test
{
    private int _val1;
    private int val1;
    public int Val1 { get; set; }
}

如果你看一下为这样的类生成的IL,你会看到Val1的后备字段将是:

.field private int32 '<Val1>k__BackingField'

<Val1>k_BackingField在c#中是错误的标识符,但在CLR中是正确的。

对不起,Nachiket,你错了。自动实现的属性val1的后备字段不称为val1。您可以简单地使用反编译器(如ildasm)进行测试。请看这里。

其次,您不能声明具有相同名称的属性和私有变量。所以你的第二个例子不正确。尝试在visual studio中输入它,您将看到相应的错误消息。

由于成员名重复,第二个代码片段无法编译。属性名称与您声明的字段名称冲突。

我相信,由于名称重复,第二个将无法编译。生成的成员变量不会与您创建的任何新成员变量冲突,它们的编译器可以保证这一点。你可以这样做,如果这是你想要的:

public class test
{
   Public int val1{ get; private set;}
}

。将setter设置为私有。但不清楚你真正想要实现的是什么。

第二个代码片段将无法编译。如果更改属性或字段名,它将进行编译。它们变成了完全不同的东西。编译器仍然会为你的自动实现的属性创建一个后台字段。所以你的属性和字段之间没有关系