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

时间:2014-03-29 18:13:59

标签: c#

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

示例:

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

上面的代码会自动生成一个名为private int val1

的私有变量

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

示例:

public class Test {
   private int val1;

   public int val1 { get; set; }
}

两个例子都是等价的吗?

5 个答案:

答案 0 :(得分:3)

编译器创建的支持字段未命名为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中是正确的。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

我很抱歉Nachiket,但你错了。自动实现的属性val1的支持字段不称为val1。你可以使用反编译器测试它,比如ild​​asm。请查看here

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

答案 3 :(得分:1)

我相信第二个不会编译,因为名字重复。生成的成员变量不会与您创建的任何新成员变量冲突,它们的编译器可以确保这一点。如果这是你想要的,你可以做这样的事情:

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

即。让setter私有化。但目前尚不清楚你真正希望实现的目标。

答案 4 :(得分:1)

您的第二个代码段将无法编译。如果您更改属性或字段名称,它将进行编译。它们将成为完全不同的东西。编译器仍将为您的支持字段 >自动实现属性。因此,您的属性和字段之间不存在任何关系。