2010-02-28 2 views
7

Учитывая следующий код клиента:Может ли конструктор вернуть субкласс?

var obj = new Class1(); 

Есть ли способ изменить конструктор Class1 так, что оно будет на самом деле возвращает подкласс (или какой-либо другой альтернативный вариант осуществления) вместо?

Я хотел бы obj получить одну из двух различных реализаций, в зависимости от некоторого состояния. Очевидно, я мог бы перейти на использование фабрики или инфраструктуры DI, но я бы хотел, если это возможно, избегать изменения кода клиента.

Я предполагаю, что ответ отрицательный, но мне интересно, есть ли какой-то умный способ сделать это.

+4

Мы рассматриваем возможность добавления функции «расширение new», которая по существу позволит вам создать статический заводский метод, который будет вызываться, когда используется «новый» оператор, так же, как методы расширения вызывают, когда «.» используется оператор. Это был бы хороший синтаксический сахар для завода. Если у вас действительно потрясающий сценарий, когда этот тип паттерна будет полезен, я бы хотел увидеть пример. –

+1

@ Эрик: пока это не пример C#, я столкнулся с ситуацией, когда это было бы полезно в C++. Я разрабатываю кросс-платформенную библиотеку, и было бы очень полезно, чтобы ABC-платформа-агностик могла возвращать экземпляр производного класса для конкретной платформы из своего конструктора. Я уверен, что при разработке с C# должны возникать аналогичные ситуации. – Mac

+0

@ Эрик Липперт - у меня для вас реальный сценарий! http://blog.hackensplat.com/2010/09/construct-something-else-c.html – billpg

ответ

4

Это невозможно.

Умные обходные пути включают замену конструктора на функцию static или (не рекомендуется) с использованием обертки вокруг базового класса и создания различных завернутых классов.

8

Вы можете заменить конструктор фабричным методом, и вернуть все, что угодно, в зависимости от параметров:

public Class2 : Class1 {} 

public static Class1 CreateClass1(bool returnDerivedClass) 
{ 
    if (returnDerivedClass) 
    { 
     return new Class2(); 
    } 
    else 
    { 
     return new Class1(); 
    } 
} 
0

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

Читайте о «Инверсии управления» и «Инъекции зависимостей», возможно, это то, что вы действительно ищете.

Приятную библиотеку можно найти here.

0

Используйте библиотеку для инъекций. Ссылка ниже представлен большой список библиотек нагнетательных там и сравнение их эффективности

http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison

Я хотел бы предложить, однако, что производительность редко критериям вы выбрали бы библиотеку инъекции на большинство приложений не инстанцирует количество объектов, которые этот парень использовал в своих тестах. Я использую NInject, который хорошо выполняет эту работу, но если бы я начал новый проект, я бы, вероятно, дал simpleinjector, похоже, что у меня есть все функции, которые я использую в NInject, и это хорошо работает в сравнении производительности.

Смежные вопросы