2016-06-16 2 views
1

Я пытаюсь преобразовать мои преобразователи на основе Action и Func в классы, чтобы я мог быстро их менять и с минимальной суетой.Generic Abstract String Converter

Класс, который будет принимать их, очевидно, должен хранить преобразователь в качестве определения переменной

private Converter converter; 

Класс у меня до сих пор:

public abstract class Converter<T> 
{ 
    public abstract bool Convert(string str, out T val); 
} 

public class StringToFooConverter : Converter<Foo> 
{ 
    public override bool Convert(string str, out Foo val) 
    { 
     //do the parsing here 
    } 
} 

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

+1

Что касается реализации не общего интерфейса, который реализуется вашим абстрактным классом? – HimBromBeere

+0

@HimBromBeere Я прочитал что-то в этом роде, но у меня возникли проблемы с пониманием интерфейса, который я мог бы реализовать без дженериков? Любые идеи, что подпись функции будет внутри интерфейса? – Questioning

ответ

4

Создать необщего интерфейс и реализовать его в абстрактном классе

interface IConverter 
{ 
    bool Convert(string str, out object val); 
} 

public abstract class Converter<T> : IConverter 
{ 
    public abstract bool Convert(string str, out T val); 
    bool IConverter.Convert(string str, out object val) 
    { 
     T result = default(T); 
     var success = this.Convert(str, out result); 
     val = result; 
     return success; 
    } 
} 

public class StringToFooConverter : Converter<Foo> 
{ 
    public override bool Convert(string str, out Foo val) 
    { 
     //do the parsing here 
    } 
} 

Как вы можете видеть интерфейс-метод просто вызывает абстрактный (общий) один. Таким образом, теперь вы можете написать это:

object anyOutObject; 
IConverter myConverter = new StringToFooConverter(); 
myConverter.Convert(myString, out anyObject); 

Однако, как вы не дают общего типа, вы должны бросить anyObject к вашему фактическому Foo -типа.

+0

Удивительный! У меня были реализации с использованием объекта, но я не мог сделать последний шаг. Очень признателен. – Questioning

+0

Только что видел ваше редактирование; что бы вы предложили в отношении передачи родового типа, если бы я хотел избежать преобразования? – Questioning

+1

Вы не можете, так как интерфейс не имеет никакого представления об общем ограничении. Однако я предположил, что именно поэтому вы не хотели использовать «Конвертер = новый StringToFooConverter()»? Вы должны каким-либо образом указать тип 'Foo', если вы хотите называть любого члена' Foo' на возвращаемом объекте. Таким образом, листинг или использование вашего текущего подхода. – HimBromBeere

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