使用C#自动实现的属性编译错误

Cha*_*adD 0 c# visual-studio-2010

AC#Noob,我正在尝试使用SharpDevelop实用程序将我的VB.NET应用程序转换为C#.

我注意到我自动实现的属性产生了很多错误.例如,请使用以下属性:

public SqlDateTime DateOfBirth {get; 组; }

每当我尝试访问隐含的底层模块级变量_DateOfBirth时,我都会收到错误.

错误699当前上下文中不存在名称"_DateOfBirth"D:\ Users\Chad\Desktop\BESI CSharp\BESI\BESI.BusinessObjects.ConvertedToC#\ ChinaVisa.cs 240 13 Besi.BusinessObjects.Converted

我可以将属性声明扩展为完整属性,但这不是必需的,我想了解为什么我会收到此错误.

And*_*are 9

您无法访问编译器创建的后备变量 - 您必须使用该属性.编译器生成的支持字段以这样的方式专门命名,以防止您访问它(它没有命名_DateOfBirth,它的名字就像<DateOfBirth>k__BackingField).

直接访问属性 - 如果需要直接操作支持字段,请不要使用自动实现的属性.

只是一个注意事项 - 属性名称是什么并不重要(它是一个实现细节,可能会在不同版本的编译器或完全不同的编译器实现上发生变化).该字段被赋予一个标识符,专门设计用于满足CLR的命名限制,但不符合C#的命名限制,因此无法编写直接访问该变量的直接C#代码.

还要记住,自动实现的属性不是公共字段.它们是编译器为您扩展的简写(有点像宏).

所以这堂课:

class Bar
{
    public object Foo { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

获得扩展到这个:

class Bar
{
    [CompilerGenerated]
    private object <Foo>k__BackingField;

    public object Foo
    {
        [CompilerGenerated]
        get
        {
            return this.<Foo>k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            this.<Foo>k__BackingField = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它仍然是一个完整的属性 - 您只是允许编译器为您编写getter和setter.

  • @Chad:属性的访问方式与字段不同,因此如果您使用自动属性并决定稍后在访问器中添加更多代码,则不会破坏引用代码的程序集.如果将字段更改为属性,则引用程序集的程序集将在不重新编译时中断. (2认同)
  • @Chad - 好问题!当您访问公共字段和公共属性时,您使用相同的语法(在两种语言中),但编译器为这些成员发出的元数据是非常不同的.这意味着调用您的类的代码可能正在使用反射(例如)来处理您的类,并且由于属性和字段的元数据不同,如果您将成员从字段切换到属性,则会破坏此客户端的代码. (2认同)