2014-01-27 4 views
4

У меня есть библиотека, которая содержит класс. Этот класс предназначен для расширения. Он будет подключаться к базе данных и генерировать записи класса, который его расширяет. Теперь я хочу вернуть массив типа расширяющегося класса. Как я могу это сделать ? Например:Возвращение массива 'this' в C#

public this[] search(string search) { 
} 

Как это сделать?

EDIT: Я использую generics, это общий класс. Это означает, что у меня нет никаких подсказок о том, какой класс, который расширит мой, будет. Поэтому я не могу просто добавить имя класса до [] ...

EDIT 2: Как было указано, возвращение массива из этого не имеет никакого смысла (тогда моя ошибка). Поэтому я хочу вернуть массив расширенного типа класса. Например:

public abstract class MappingObject { 
    public ExtendedClassType[] search (string search) { 
    } 
} 

Найдено решение ._. Я сожалею, что это было довольно просто ...

public abstract class MappingObject<T> where T : new() { 
    public static List<T> search(string search) { 
    } 
} 
+3

Укажите _extend_. Почему бы вам не заменить «this' на фактическое имя класса? –

+4

Почему вы не можете использовать фактическое имя класса? 'public MyClass [] search (string s) {}' – noelicus

+1

Вы не можете и не должны. Это признак неправильного дизайна и непонимания ООП. – Euphoric

ответ

4

Я не совсем уверен, что вы ищете, но на основе нескольких подсказок в вашем вопросе вы можете рассмотреть что-то вроде следующего (обозначаемого в качестве Curiously Recurring Template Pattern):

public abstract class MyBaseClass<T> : where T : MyBaseClass<T> 
{ 
    public abstract T[] Search(string search); 
} 

public class DerivedClass : MyBaseClass<DerivedClass> 
{ 
    public override DerivedClass[] Search(string search) 
    { 
     return new DerivedClass[0]; 
    } 
} 

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

Эта конкретная идея используется в таких инфраструктурах, как CSLA.NET, чтобы подвергать производному классу сильные ссылки на себя при наследовании от определенных базовых классов. Это, как правило, «синтаксический сахар», и он не позволяет бросать много, чтобы использовать вещи по своему типу при их из базовых классов. Сам базовый класс по-прежнему не должен понимать, какие типы происходят от него.


Eric Lippert talks about this pattern on his old MS blog. У этого есть свои подводные камни, и он раскрывает то, как его можно злоупотреблять. Я лично придерживаюсь подхода, что осознание этих ошибок и возможностей для злоупотреблений является достаточно хорошим, пока все проверено. Я счастлив использовать что-то, что может противоречить рекомендациям или принципам, если это ясно (нет достаточно дополнительной информации, чтобы понять, ясно ли это в данном конкретном случае). Задания Eric:

Все, что сказало, на практике бывают случаи, когда использование этого шаблона действительно прагматично решает проблемы способами, которые трудно моделировать иначе в C#; это позволяет вам немного обойти тот факт, что у нас нет ковариантных типов возврата для виртуальных методов и других недостатков системы типов. То, что он делает это таким образом, который, строго говоря, не принуждает к любым ограничениям, которые могут вам понравиться, является неудачным, но в реалистичном коде обычно не является проблемой, которая препятствует доставке продукта.

Мой совет - подумать очень сложно, прежде чем реализовать этот вид любопытный шаблон в C#; делать преимущества для клиента действительно перевешивают расходы, связанные с ментальной нагрузкой, которую вы размещаете по коду ?

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

+0

А что, если я получу DerivedClass? И я знаю, что это шаблон, и я знаю, что я где-то читал, что это плохая модель. Но я не помню. – Euphoric

+0

Ну тогда не происходит от DerivedClass. –

+0

@MatthewWatson Тот факт, что шаблон работает только для одного уровня наследования, меня сильно меняет. В основном нарушает любой разумный дизайн ООП. – Euphoric

1

«это» означает этот экземпляр класса, поэтому ваш код в данный момент в основном говорит «Я хочу вернуть массив этого экземпляра MyClass», который на самом деле не имеет смысла.

Я думаю, что вы хотите сказать: «Я хочу, чтобы вернуть массив этого типа объекта класса»

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

public YourClassName[] Search(string search) 
{ 

} 
0

ли вы имеете в виду,

public class YourClass 
{ 
    public T[] Search<T>(string search, Convertor<SearchResult, T> convertor) 
    { 
     ... 
     List<SearchResult> results = ... 
     return results.ConvertAll(convertor).ToArray(); 
    } 
} 

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

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