【问题标题】:Using C# reflection to call a constructor使用 C# 反射调用构造函数
【发布时间】:2015-05-19 15:49:30
【问题描述】:

我有以下场景:

class Addition{
 public Addition(int a){ a=5; }
 public static int add(int a,int b) {return a+b; }
}

我正在通过以下方式调用 add in another class:

string s="add";
typeof(Addition).GetMethod(s).Invoke(null, new object[] {10,12}) //this returns 22

我需要一种类似于上面的反射语句的方式来使用Addition(int a)创建一个Addition类型的新对象

所以我有字符串s= "Addition",我想使用反射创建一个新对象。

这可能吗?

【问题讨论】:

  • 为什么要使用反射?反射会带来性能损失,从长远来看会产生维护问题......
  • @Patrick,很多情况下只要达到用户目标,性能损失就可以忽略。

标签: c# reflection constructor


【解决方案1】:

我不认为 GetMethod 会这样做,不会 - 但 GetConstructor 会。

using System;
using System.Reflection;

class Addition
{
    public Addition(int a)
    {
        Console.WriteLine("Constructor called, a={0}", a);
    }
}

class Test
{
    static void Main()
    {
        Type type = typeof(Addition);
        ConstructorInfo ctor = type.GetConstructor(new[] { typeof(int) });
        object instance = ctor.Invoke(new object[] { 10 });
    }
}

编辑:是的,Activator.CreateInstance 也可以。如果您想对事物有更多控制权,请使用GetConstructor,找出参数名称等。如果您只是想调用构造函数,Activator.CreateInstance 非常棒。

【讨论】:

  • 是的,但是您必须实现所有重载解析规则才能选择正确的构造函数。而如果您致电msdn.microsoft.com/en-us/library/wcxyzt4d.aspx,运行时将为您完成
  • 所以如果你想缓存一个委托,GetConstructor是首选(多次调用同一个构造函数时性能增强),但一次性使用Activator会更容易。
  • @AkshayJoy:“它不工作”的信息还不够。我已经告诉过你如何机械地转换它——另一种选择是确保你理解 C# 代码,然后确保你知道构造数组的 VB 语法。不想刻薄,如果这是一个太大的挑战,那么你真的应该真的远离反思。
  • 知道了,谢谢 Jon Skeet Dim params(0) As Type params(0) = GetType(FViewer) Dim constructorInfoObj As ConstructorInfo = objType.GetConstructor(params)
  • @SarathAvanavu:无论如何你都不会通过反思来做到这一点......不清楚你在说什么情况,所以可能值得提出一个新问题(在搜索类似问题之后,当然)。
【解决方案2】:

是的,你可以使用Activator.CreateInstance

【讨论】:

  • 这确实需要一个正确的答案
  • 有趣的是,当构造函数有参数时,反射比Activator.CreateInstance快:gist.github.com/KallDrexx/d08a60f2d807673af1d9e90e07d61aeb
  • @KallDrexx:您的基准测试没有正确测量反射成本,因为大部分是在测量函数之外完成的。将typeof(Program).GetConstructor(new[] {typeof(int)}); 移动到调用它的函数中,以便进行更公平的比较。即便如此,您已经提前选择了精确匹配的重载,而 Activator 必须在具有相同数量参数的所有构造函数中进行重载解析。
  • @BenVoigt 虽然是真的,但如果你刷新你会看到一个新的测试,我确实在其中添加了这个测试用例。即使考虑到GetConstructor() 调用的时间,它仍然是 ACtivator.CreateInstance 时间的 2/3。我也不认为 Activator.CreateInstance 缓存它可能发生的任何反射调用是不合理的(因为它可能会再次调用它是合理的),但无论它的成本是多少,它显然都没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
相关资源
最近更新 更多