c# - C# 属性总是有备份字段 "behind the scene"吗?

标签 c# properties cil

我知道当我们在 C# 中使用属性时,编译器总是在 CIL 中为它们生成 getter 和 setter(即 get_PropertyName 和 set_PropertyName),例如,考虑以下代码:

    class Program
    {
        class Test
        {
            public string Name { get; set; }
        }
        static void Main(string[] args)
        {
            //Here I'm using reflection to inspect methods of Test class
            Type type = typeof(Test);
            foreach (var item in type.GetMethods())
            {
                Console.WriteLine(item.Name);
            }
        }
    } 

该程序将使用Test 方法产生输出,其中将有get_Nameset_Name - 我的getter 和setter谈论。 根据我的理解,如果 getter 和 setter 是“在幕后”创建的,那么也应该创建一个支持字段,getter 和 setter 从中/向其获取/设置值。 因此,在前面的示例中,我可以使用反射来检查 Test 类的字段,如下所示:

    static void Main(string[] args)
    {
        Type type = typeof(Test);
        foreach (var item in type.GetFields())
        {
            Console.WriteLine(item.Name);
        }
    } 

这个程序的输出是空的,我假设这是因为创建的支持字段具有 private 访问权限,所以我们看不到它。但是因为我不知道如何检查它,你能告诉我是否总是创建一个支持字段(即使我们有一个只有 get;set; 的简单属性) ) ?

最佳答案

如果您指的是简单的属性,例如:

{get;set;}

或:

{get;}

然后是的,有一个字段;添加 BindingFlags.NonPublic | BindingFlags.Instance给你的GetFields()打电话,你会看到它:

foreach (var item in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
    Console.WriteLine(item.Name);
}

它通常有一个不可发音的名字,涉及 <> - 你的是 <Name>k__BackingField在我的机器上 - 但是:这个名称是一个编译器特性(虽然很多序列化等库都使用它,所以它不太可能改变)。

但是:不,属性本身并不总是涉及字段;例如:

public int Value => 42; // no field

public int Name { get { return obj.Name; } set { obj.Name = value; } }

关于c# - C# 属性总是有备份字段 "behind the scene"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43112091/

相关文章:

c# - DateTime.Parse 在 C# 中抛出异常

c# - 在 Windows Vista 上使用 C# .Net 获取我连接的无线网络的 SSID

maven-2 - 指示父目录的 Maven2 属性

python - 如何将小部件绑定(bind)到 Kivy 应用程序中的值

go - 如何检查嵌套结构中是否存在键

c# - 有没有一种简单的方法来获取C#(或CIL)中当前堆栈帧中的所有局部变量

c# - 如何将列表从 View 传递到 Controller ?

javascript - 如何将数据从 C# 传递到 javascript 函数?

c++ - 理解托管 C++

c# - Visual Studio 编译器如何将安全属性编译为 CIL?