如何动态地将类型传递给通用工厂?

时间:2011-06-23 21:27:00

标签: c# generics .net-4.0 factory-pattern

我的工厂定义如下:

  public IPopulator CreatePopulator<T>(ReportItem Item) where T : IReportElement
    {
        if (typeof(T) == typeof(BarChartElement))
        {
            return BarChartPopulator.Create(Item);
        }
        else
        {
            throw new NotSupportedException(string.Format("Type: {0} is not suppported by {1}", typeof(T).Name, this.GetType().Name));
        }
    }

在调用此方法的类中,我有一个这样的变量:

IReportElement MyElement { get; set; }

假设MyElement被实例化为实现IReportElement的类型,我如何使用此变量调用我的工厂?

我试过了

Type VariableType = MyChartElement.GetType();
PopulatorFactory.CreatePopulator<VariableType>(new Chart());

并且

PopulatorFactory.CreatePopulator<MyVariable.GetType()>(new Chart());

我可以写一个switch语句,但我觉得应该有一些方法让我传递我的类型。这可能吗 ?

2 个答案:

答案 0 :(得分:3)

您不能将变量用作通用参数。他们可以提供类型安全的唯一方法是在编译时 知道类型。

您描述的工厂方法往往被实现为switch语句,并且没有任何内在错误。您可以将枚举类型传递给工厂方法,该方法将返回实现IReportElement的类型的实例。

无论如何,我不太了解你想要完成的任务。您的通用工厂方法正在检查参数的类型。如果你必须检查类型,那么,它不再是通用的,那么重点是什么?

也许您可以更深入地了解一下您实际尝试使用此代码解决的问题。你可能还有一个更好的选择,你尚未考虑过。

答案 1 :(得分:2)

如果你正在使用一个无法改变的图书馆,就像@Dan Bryant建议的那样,这样的事情应该有效。

typeof (PopulatorFactory)
  .GetMethod("CreatePopulator")
  .GetGenericMethodDefinition()
  .MakeGenericMethod(new[] {myVariable.GetType()})
  .Invoke(null, new object []{new Chart ()});