2016-01-28 3 views
1

Привет, я использую Visual Studio 2005 (потому что мне нужна компактная поддержка фреймворка), и моя проблема связана с дженериками.Как преобразовать класс с общим типом в класс с объектом как общий тип в C#

Я создал абстрактный класс AbstractDAO, который моя база

От этого я создаю другие классы, как DocumentDAO, HeaderDAO и т.д., которые представляют различные таблицы на моей базе данных

То, что я хочу сделать, это получить определенное количество вышеупомянутых классов DAO, но как AbstractDAO (абстрактный класс имеет ряд конкретных реализаций, которые я хотел использовать)

То, что я пытался это

AbstractDAO<object> dao = new DocumentDAO(); 
AbstractDAO<object> dao = (AbstractDAO<object>)new DocumentDAO(); 
AbstractDAO<T> dao = new DocumentDAO(); 

мне нужно выше, потому что я создал функцию, которая передает данные из одной таблицы в другую аналогичную таблицу в другой базе данных, так что это будет (если он работал) пойти что-то вроде этого

AbstractDAO<object> dao_local = new DocumentDAO(local_database); 
AbstractDAO<object> dao_remote = new DocumentDAO(remote_database);  
do_transfer(dao_local,dao_remote) 

void do_transfer(AbstractDAO<object> from, AbstractDAO<object> to) { 
    List<object> items = from.get_all(); 
    to.insert(items); 
} 

Есть ли любой способ сделать это?

+0

Чувак - как Вы excepct, чтобы иметь возможность присвоить значение типа B к переменной типа A (по крайней мере, это то, что делает ваша первая строка ..) – Marty

+0

Это похоже на основы C#: AbstractDOA doa = new DocumentDOA(); или – Marty

+0

Это будет работать только если вы класс, как иерархия: – Jens

ответ

0

Так что я, наконец, нашел ответ на то, что я пытался сделать, вместо того, чтобы назначить abstractDAO на то, что я создал завод, который будет извлекать необходимый AbstractDAO согласно какому типу родового был, и использовать эту функцию

private bool transfer<T>(){ 
    AbstractDAO<T> local = DAOFactory.get<T>(local_database); 
    AbstractDAO<T> remote = DAOFactory.get<T>(remote_database); 
    List<T> items = local.get_all(); 
    foreach (T item in items) { 
     remote.insert(item); 
    } 
} 

Таким образом, я могу назвать эту функцию следующим образом: transfer < Документ>(); Передача < Разрядник>();

и т.д., и сделать полный перенос

редактировать: только для полноты трясти это завод я создал

public static AbstractDAO<T> get<T>(Database database) { 
     Type t = typeof(T); 
     if (t == typeof(Document)) { 
      return new DocumentDAO(database) as AbstractDAO<T>; 
     } else if (t == typeof(Header)) { 
      return new HeaderDAO(database) as AbstractDAO<T>; 
     } etc. 
    } 
1

Это будет работать только если ваш класс иерархия выглядит так:

class DocumentDAO : AbstractDAO<object> { 
    //... 
} 

К вашему комментарию, кажется, что у вас есть иерархия типа так:

class DocumentDAO : AbstractDAO<SomeType> { 
    public override SomeType Foo() { 
     //... 
     return someValue; 
    } 
    //... 
} 
class AbstractDAO<T> { 
    public abstract T Foo(); 
    //... 
} 

Вы, вероятно, хотите, чтобы реорганизовать AbstractDAO для реализации не общего интерфейса, такого как IAbstractDAO:

class IAbstractDAO { 
    object Foo(); 
    //... 
} 

class AbstractDAO<T> { 
    public object Foo() { 
     return Foo(); 
    } 
    public abstract T Foo(); 
    //... 
} 
+0

Моя иерархия, как тот, который вы публикуемые в прошлом (без интерфейса) класса 'AbstractDAO {} класса DocumentDAO: AbstractDAO {}' Но добавляющего это: 'общественного Списка get_objects() { Списка элементов = get_all(); возвращать товар как Список ; } public int insert_object (объект obj) { return insert ((T) obj); } В абстрактном dao, кажется, не возникают ошибки, поэтому я предполагаю, что могу использовать это, это не совсем то, что я хотел (т. Е. Возможность подкласса к суперклассу), но я могу работать с этим, благодаря – Cruces

0

Вы можете использовать Automapper передать свои объекты, как это:

void do_transfer(AbstractDAO<FirstType> from, AbstractDAO<SecondType> to) 
{ 
    Mapper.Initialize(cfg=>cfg.CreateMap<FirstType, SecondType>); 

    List<FirstType> fromItems = from.get_all(); 
    List<SecondType> itemsToInsert = 
     Mapper.Map<List<FirstType>, List<SecondType>>(fromItems); 
    to.insert(itemsToInsert); 
} 

По умолчанию automapper будет отображать поля с одинаковыми именами. Вы можете создать configurations для отображения сложного типа.

+0

моей проблеме не то, что я не могу преобразовать тип from from to, моя проблема в том, что я хочу иметь общий аргумент для этой функции, если это возможно. Т.е. либо 'do_transfer (AbstractDAO из, AbstractDAO к)' или ' do_transfer (AbstractDAO из, AbstractDAO к)' дело в том, что я не могу бросить AbstractDAO к AbstractDAO даже если в объекте теории является суперклассом всех объектов. – Cruces

+0

Вы пытались объявить передачу как этот 'DoTransfer (Dao источник, Dao dest)'? –

1

Любая реализация AbstractDAO<T> скомпилирована в отдельный тип объекта, где T заменяется типом. См. «Is generics runtime or compile time polymorphism?» для получения дополнительной информации о том, как это происходит. Короче говоря, не позволяйте <T> вас обмануть.

Это означает, что вы не можете назначить DocumentDAO по номеру AbstractDAO<object> больше, чем вы можете назначить ему String. Также общий тип - это не то же самое, что унаследовать, что похоже на то, чего вы пытаетесь достичь.

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

Первый - operate on interfaces. Вы создаете интерфейс для общих свойств и имеете AbstractDAO<T> или любое другое унаследованное от этого. Тогда большую часть времени вы просто работаете на интерфейсах. Точно, как вы его организуете, зависит от вас.

Второй способ заключается в выполнении shallow copy объекта. Это означает копирование значений и ссылок с одного объекта на другой. Для этого вы обычно используете объект mapper, например AutoMapper. This tutorial должен вас начать ..

+0

Спасибо, что много помогли, я пошел с другим решением, я опубликую его ниже, но литература, безусловно, помогла мне лучше понять работу дженериков – Cruces

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