(Этот ответ в некотором роде два разных ответа, в зависимости от значения вашего вопроса. Надеюсь, одна часть его полезна, в любом случае:)
Вероятно, лучший способ - передать аргумент, который является функцией, которую можно использовать для создания нового элемента управления в нужное время. Если вы используете C # 3, это так просто:
Form.RegisterControl("Text", () => new Text())
В качестве альтернативы, вы можете сделать его универсальным методом с двумя ограничениями: один для элемента управления и один для конструктора без параметров.
public void RegisterControl<T>(string name) where T : Control, new()
затем назовите его с:
Form.RegisterControl<Text>("Text");
Form.RegisterControl<DateTimeControl>("DateTime");
RegisterControl
должен был бы помнить typeof(T)
в любом хранилище, которое он использует, но по крайней мере тогда можно было бы с достаточной уверенностью предположить, что Activator.CreateInstance(Type)
сработает позже - и у вас будет проверка во время компиляции.
Лично мне нравится гибкость первой формы, хотя - если вы передаете делегат, он может выбрать использование одиночного или, возможно, некоторого внутреннего или даже частного конструктора (в зависимости от того, откуда он вызывается). Вы также можете использовать делегата, который также получил соответствующие данные:
Form.RegisterControl("Text", data => new Text(data));
Вы не можете выразить конструктор такого типа с общим ограничением, и в любом случае это будет относительно трудно вызвать позже.
РЕДАКТИРОВАТЬ: Возможно, что и я, и Мердад неправильно истолковали вопрос. У вас действительно есть различные перегрузки RegisterControl
в зависимости от типа элемента управления? Если это так, то единственные способы прямого вызова правильной перегрузки во время выполнения - это либо использовать отражение, либо использовать динамическую типизацию в C # 4.
Другая альтернатива - использовать двойную диспетчеризацию - поместить в сам элемент управления метод, который знает, как зарегистрироваться в форме. Это будет указано в интерфейсе или базовом классе, но переопределено в конкретных подклассах. Итак, ваш код, который на данный момент:
Form.RegisterControl("Text", control);
станет:
control.RegisterWith(Form, "Text");
Чтобы мог затем вызвать корректную перегрузку без проблем.
В основном вам нужно помнить, что разрешение перегрузки выполняется во время компиляции, но разрешение переопределения выполняется во время выполнения - поэтому, если вы хотите создать что-то динамическое, попробуйте применить к нему полиморфизм.