【问题标题】:Best way to invoke factory method via reflection通过反射调用工厂方法的最佳方法
【发布时间】:2012-01-24 16:00:42
【问题描述】:

我有以下课程(带有私有 .ctor 和公共工厂方法)

public class TypeWithFactoryMethods
{
    private TypeWithFactoryMethods()
    {
    }

    public static TypeWithFactoryMethods Create()
    {
        return new TypeWithFactoryMethods();
    }
}

通过反射调用公共工厂方法 (Create) 以获取该类型的实例的最佳方式是什么?

【问题讨论】:

  • 在这种情况下使用反射调用静态方法而不是反射调用构造函数有直接的好处吗?
  • 我需要它,这样我就可以获得所有工厂方法并选择调用哪一个(传递参数)。
  • 请记住,在此类工作中使用反射通常会产生代码异味。
  • 是的!尽管我试图实现它,但它不适用于生产。不过非常感谢..

标签: c# reflection


【解决方案1】:

不太确定目标是什么,但这样做可以:

Type type = typeof(TypeWithFactoryMethods);
MethodInfo info = type.GetMethod("Create", BindingFlags.Static | BindingFlags.Public);
object myObject = info.Invoke(null, null);
myObject.GetType(); //returns TypeWithFactoryMethods

评论后更新

如果您想查找所有返回您指定类型的方法,您可以使用 Linq 来查找它们:

Type type = typeof(TypeWithFactoryMethods);
List<MethodInfo> methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public)
    .Where(m => m.ReturnType == type).ToList();
foreach (var method in methods)
{
    ParameterInfo[] parameters = method.GetParameters(); //use parameters to decide how to invoke
    object myObject = method.Invoke(null, null);
    myObject.GetType(); //returns TypeWithFactoryMethods
}

【讨论】:

  • 我想发现“创建”方法。我在运行时不知道方法名称。
  • @Nikos Baxevanis 更新了我的答案
  • 所以您想发现一个公共静态方法,该方法返回包含它的类型并采用 x-many 参数?
  • @Adam Houldsworth 是的,没错。
  • @Bas 做到了!非常感谢。 :-)
【解决方案2】:

相同结果的代码更少:

var param = Expression.Parameter(typeof (TypeWithFactoryMethods));
            var method = Expression.Call(null,typeof(TypeWithFactoryMethods).GetMethod("Create"));
            Expression.Lambda<Action>(method).Compile()();

【讨论】:

  • 是的,表达式树在这个例子中真的很有帮助,但不幸的是你没有重新实现正确的答案。正如您在 Bas 的更新中看到的,工厂方法的名称在编译时是未知的。所以请加入一些小的 LINQ 糖以使其完全匹配。
猜你喜欢
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
相关资源
最近更新 更多