c# - 如何使用反射获取C#中auto属性的默认值?

原文 标签 c# .net reflection

所以我有这堂课

public class MyClass
{
    public int Id {get; set;} = 5
}


使用反射如何获得5

我试图避免创建MyClass的实例。似乎没有必要。

编辑:称为“自动属性初始化”值

来自:http://geekswithblogs.net/WinAZ/archive/2015/06/30/whatrsquos-new-in-c-6.0-auto-property-initializers.aspx

最佳答案

该类实际上被编译为:

public class MyClass
{
    private int MyClass___1<Id> = 5;
    public int Id
    {
        get { return MyClass___1<Id>; }
        set { MyClass___1<Id> = value; }
    }
}


而这等效于:

public class MyClass
{
    private int MyClass___1<Id>;

    public MyClass()
    {
        MyClass___1<Id> = 5;
    }

    public int Id
    {
        get { return MyClass___1<Id>; }
        set { MyClass___1<Id> = value; }
    }
}


因此,除了反编译构造函数或构造类型的实例之外,您无法获得该值。

如果您是该类型的作者,则最好的方法是将[DefaultValue(...)]属性应用于该属性,该属性可以通过反射读取。许多序列化库也将使用此值,以避免序列化具有默认值的属性。

您的课程将如下所示:

public class MyClass
{
    [DefaultValue(5)]
    public int Id { get; set; } = 5;
}




话虽如此,这是一个演示LINQPad的小型Mono.Cecil程序:

void Main()
{
    var assembly = AssemblyDefinition.ReadAssembly(GetType().Assembly.Location);
    var myClassType =
        (from module in assembly.Modules
         from type in module.Types
         where type.Name == "UserQuery"
         from nestedType in type.NestedTypes
         where nestedType.Name == "MyClass"
         select nestedType).FirstOrDefault();

    var ctor =
        (from method in myClassType.Methods
         where method.IsConstructor
         select method).FirstOrDefault();

    foreach (var instruction in ctor.Body.Instructions)
        Console.WriteLine(instruction.ToString());
}

public class MyClass
{
    public int Id { get; set; } = 5;
}


输出:

IL_0000: ldarg.0
IL_0001: ldc.i4.5
IL_0002: stfld System.Int32 UserQuery/MyClass::<Id>k__BackingField
IL_0007: ldarg.0
IL_0008: call System.Void System.Object::.ctor()
IL_000d: ret


因此在这种情况下可能是可行的,但是其他类型的常量等(如对静态方法的调用)将不容易处理。

简而言之,创建实例!

相关文章:

c# - C#使用list时如何遍历列表中的每个项目

c# - 标签上的透明标签

java - 为什么我的自定义SecurityManager第16次使用Constructor.newInstance创建对象时会导致异常?

c# - 如何获得控制器的POST操作方法?

c# - TypeCast使用类的类型/字符串名称

c# - 如何使用LINQ填充元组?

c# - 如何使用SQL必需的库发布数据库Winform应用程序

c# - 使用NSubstitute在AutoFixture中是否可能/受支持从代理接口返回自动值

c# - 实体框架-遍历属性以进行更新

.net - 将.NET DateTime转换为OracleDate