我知道当我们在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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这一计划将产生的输出与方法Test,其中还会有get_Name和set_Name-我说的是getter和setter方法.根据我的理解,如果getters和setter是在"幕后"创建的,那么应该创建一个支持字段,getter和setter获取/设置值.因此,从前面的示例中,我可以使用反射来检查Test类的字段,如下所示:
static void Main(string[] args)
{
Type type = typeof(Test);
foreach (var item in type.GetFields())
{
Console.WriteLine(item.Name);
}
}
Run Code Online (Sandbox Code Playgroud)
这个程序的输出是空的,我认为这是因为创建的支持字段具有private访问权限,因此我们无法看到它.但由于我不知道如何检查它,你能告诉我是否总是创建一个支持字段(即使我们只有一个简单的属性get;和set;)?
Mar*_*ell 14
如果你的意思是简单的属性:
{get;set;}
Run Code Online (Sandbox Code Playgroud)
要么:
{get;}
Run Code Online (Sandbox Code Playgroud)
然后是的,有一个领域; 添加BindingFlags.NonPublic | BindingFlags.Instance到您的GetFields()通话中,您会看到它:
foreach (var item in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
Console.WriteLine(item.Name);
}
Run Code Online (Sandbox Code Playgroud)
它通常有一个不可启动的名称涉及<>- 你的是<Name>k__BackingField在我的机器上 - 但是:这个名称是一个编译器功能(虽然很多序列化等库都使用它,因此它不太可能改变).
但是:不,财产本身并不总是涉及领域; 例如:
public int Value => 42; // no field
Run Code Online (Sandbox Code Playgroud)
要么
public int Name { get { return obj.Name; } set { obj.Name = value; } }
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 13
但由于我不知道如何检查它,你能告诉我是否总是创建一个备份字段(即使我们有一个只有get的简单属性;并设置;?
一个自动执行的财产,如
public int ReadWriteProperty { get; set; }
public int ReadOnlyProperty { get; }
Run Code Online (Sandbox Code Playgroud)
确实总会有一个由编译器生成的支持字段.但是如果你提供自己的getter/setter实现,那么编译器就不会生成一个字段:
public int Zero => 0;
public int IgnoresSetter
{
get { return 10; }
set { /* Meh. Whatever you say, I'm still going to return 10 in the getter... */ }
}
Run Code Online (Sandbox Code Playgroud)
这些都不会导致生成字段.
| 归档时间: |
|
| 查看次数: |
731 次 |
| 最近记录: |