c# - 是否可以使用反射从构造函数中获取可选参数值?

标签 c# reflection

给定这样一个类:

public abstract class SomeClass
  {
      private string _name;
      private int _someInt;
      private int _anotherInt;

      public SomeClass(string name, int someInt = 10, int anotherInt = 20)
      {
          _name = name;
          _someInt = someInt;
          _anotherInt = anotherInt;
      }
  }

是否可以使用反射获取可选参数的默认值?

最佳答案

让我们看一个基本的程序:

class Program
{
    static void Main(string[] args)
    {
        Foo();
    }
    public static void Foo(int i = 5)
    {
        Console.WriteLine("hi"   +i);
    }
}

并查看一些 IL 代码。

对于 Foo:

.method public hidebysig static void  Foo([opt] int32 i) cil managed
{
  .param [1] = int32(0x00000005)
  // Code size       24 (0x18)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "hi"
  IL_0006:  ldarg.0
  IL_0007:  box        [mscorlib]System.Int32
  IL_000c:  call       string [mscorlib]System.String::Concat(object,
                                                              object)
  IL_0011:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0016:  nop
  IL_0017:  ret
} // end of method Program::Foo

对于主要:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       9 (0x9)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldc.i4.5
  IL_0002:  call       void ConsoleApplication3.Program::Foo(int32)
  IL_0007:  nop
  IL_0008:  ret
} // end of method Program::Main

请注意,main 有 5 个硬编码作为调用的一部分,并且在 Foo 中。调用方法实际上是对可选值进行硬编码!该值位于调用站点和被调用站点。

您将能够使用以下形式获取可选值:

typeof(SomeClass).GetConstructor(new []{typeof(string),typeof(int),typeof(int)}) .GetParameters()[1].RawDefaultValue

在 MSDN for DefaultValue(在另一个答案中提到):

此属性仅在执行上下文中使用。在仅反射上下文中,改用 RawDefaultValue 属性。 MSDN

最后是 POC:

static void Main(string[] args)
{
   var optionalParameterInformation = typeof(SomeClass).GetConstructor(new[] { typeof(string), typeof(int), typeof(int) })
   .GetParameters().Select(p => new {p.Name,  OptionalValue = p.RawDefaultValue});

   foreach (var p in optionalParameterInformation)
      Console.WriteLine(p.Name+":"+p.OptionalValue);

   Console.ReadKey();
}

http://bartdesmet.net/blogs/bart/archive/2008/10/31/c-4-0-feature-focus-part-1-optional-parameters.aspx

关于c# - 是否可以使用反射从构造函数中获取可选参数值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14009359/

相关文章:

java - 使用 MethodHandle 查找最具体的重载方法

php - 为什么在调用反射方法时按引用传递变量不起作用?

C# 无法修改数据库

c# - 如何在 OpenTK 中设置无限 FPS?

c# - SQL 从两个表中选择数据(一行 -> 多行)

c# - session 过期后从数据库中删除它吗?

用于检测未使用方法的 C# 属性

c# - 为什么 AcquireTokenByAuthorizationCode 不返回 RefreshToken

go - 遍历具有嵌入结构的结构

c# - 我如何使用反射找到数据注释属性及其参数