您好我使用Visual Studio 2005(因为我需要紧凑的框架支持),我的问题是使用泛型。
我创建了一个名为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 :(得分: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();
//...
}
答案 1 :(得分:1)
AbstractDAO<T>
的任何实现都被编译为单独的对象类型,其中T被替换为类型。见&#34; Is generics runtime or compile time polymorphism?&#34;有关如何发生这种情况的更多信息。简而言之,不要让<T>
欺骗你。
这意味着您无法将DocumentDAO
分配给AbstractDAO<object>
,只能为其分配字符串。通用类型也与继承不同,这似乎是您要实现的目标。
在任何一种情况下,都有两种标准解决方案,如前所述。
第一个是operate on interfaces。您可以为公共属性创建一个接口,并使用AbstractDAO<T>
或其他任何继承。然后大多数时候你只是简单地操作接口。具体如何组织它取决于你。
第二个是执行对象的shallow copy。这意味着将值和引用从一个对象复制到另一个对象。为此,您通常使用像AutoMapper这样的对象映射器。 This tutorial应该让你开始......
答案 2 :(得分: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。
答案 3 :(得分: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);
}
}
这样我可以像这样调用这个函数: 转移&LT;文件&gt;(); 转移&LT;标题&gt;();
等。并进行全面转移
编辑:只是为了完整性&#39;摇这是我创建的工厂
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.
}