Как динамически передать тип универсальной фабрике? - PullRequest
0 голосов
/ 24 июня 2011

У меня есть фабрика, определенная так:

  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());

Я мог бы написать заявление о переключении, но я чувствую, что должен быть какой-то способ передать мой тип. Это возможно ?

Ответы [ 2 ]

3 голосов
/ 24 июня 2011

Вы не можете использовать переменные в качестве общих аргументов.Единственный способ обеспечить безопасность типов - это, если тип известен в время компиляции .

Фабричные методы, как вы описываете, имеют тенденцию быть реализованными как операторы switch, и в этом нет ничего изначально неправильногос этим.Вы можете передать перечислимый тип вашему фабричному методу, который, в свою очередь, вернет экземпляр типа, который реализует IReportElement.

Я все равно не совсем понимаю, чего вы пытаетесь достичь.Ваш общий фабричный метод проверяет тип аргумента.Если вам нужно проверить тип, тогда, ну, он больше не является общим, так какой смысл?

Возможно, вы могли бы немного углубиться в вопрос, какую проблему вы на самом деле пытаетесь решить с помощью этого.код.Возможно, есть лучшая альтернатива, которую вы еще не рассматривали.

2 голосов
/ 24 июня 2011

Если вы работаете с библиотекой, которая не может измениться в соответствии с предложением @Dan Bryant, что-то вроде этого должно сработать.

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