Преимущество Activator.CreateInstance в этом сценарии - PullRequest
1 голос
/ 03 февраля 2011

Я просто просматривал некоторые статьи по рефлексии и дженерикам и наткнулся на следующий код:

public static T CreateControlInstance<T>(FormControl parent) 
    where T : FormControl
{            
    T control = GetControlInstance<T>(parent);
    //do something with control
} 

public static T GetControlInstance<T>(FormControl parent)
{
      return (T)Activator.CreateInstance(typeof(T), new object[] { parent });
} 

Эти методы были использованы так:

MyButton b = CreateControlInstance<MyButton>(SomeformInstance);

Многие элементы управления были созданы таким образом. Я просто хотел бы знать:

Q1 . Каковы преимущества этого подхода?

Q2 . Каковы преимущества этого подхода, учитывая, что типы экземпляров объекта известны во время компиляции? (Я предполагаю, что кнопка и FormControl как-то связаны с System.Windows.Forms.Control)

Edit:
Я нашел что-то подобное, сделанное здесь Создать экземпляр универсального типа?

В основном я хочу создать тип (известного типа) из строк, которые были прочитаны во время выполнения?
Я хотел избежать длинного списка if-then-else при создании объектов определенного типа в зависимости от строки ... но не имел понятия.
У любого есть лучшее решение, так что можно избежать отражения, чтобы создать элементы известного типа.
Конец редактирования

Ответы [ 3 ]

3 голосов
/ 03 февраля 2011

Проблема с обобщениями в том, что вы не можете определить ограничение для сложного конструктора.Единственным ограничением является наличие пустого конструктора.

public static T CreateInstance<T>() where T : new()
{
  return new T();
}

Однако, если вы хотите передать параметр, вам придется использовать другие методы, такие как Activator.CreateInstance.Вы также можете использовать лямбду.

public static T CreateInstance<T>(Func<FormControl, T> builder, FormControl parent)
{
  return builder(parent);
}

Но вам придется предоставить определенную лямбду для построения вашего объекта, для каждого отдельного объекта.

MyButton b = CreateInstance<MyButton>(parent => new MyButton(parent), SomeformInstance);

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

var b2 = CreateInstance<MyOtherButton>(
  parent => new MyOtherButton("name", 42, parent), SomeformInstance
);
2 голосов
/ 08 февраля 2011

Если вы собираетесь создать множество элементов управления таким образом, вы заметите, что ваше приложение будет работать медленно.Это происходит потому, что Activator.CreateInstance в 10000 раз медленнее, чем простой new ().Имейте это в виду.

0 голосов
/ 03 февраля 2011

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

Вы можете, например, расширить метод CreateControlInstance<T> с помощью дополнительной обработки, которую необходимо выполнить для постоянного контроля.

Однако, когда выбор между

MyButton b = CreateControlInstance<MyButton>(SomeformInstance);

и

MyButton b = new MyButton(SomeformInstance);

Нет абсолютно никаких причин не выбирать последнее. Первый будет работать хуже и бесполезно загромождать ваш код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...