如何在 C# 中将具有泛型类型的类转换为具有对象作为泛型类型的类
本文关键字:泛型类型 对象 转换 | 更新日期: 2023-09-27 18:32:11
您好,我正在使用Visual Studio 2005(因为我需要紧凑的框架支持),我的问题是泛型。
我创建了一个名为AbstractDAO的抽象类,这是我的基础
从那里我正在创建其他类,如DocumentDAO,HeaderDAO等,它们代表我的数据库上的不同表
我希望做的是检索一定数量的上述DAO类,但作为一个抽象DAO(抽象类有许多我希望使用的具体实现)
我尝试的是
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);
}
有没有办法做到以上?
这只有在您的类层次结构如下所示时才有效:
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();
//...
}
AbstractDAO<T>
的任何实现都会编译为单独的对象类型,其中 T 被替换为类型。请参阅"泛型运行时还是编译时多态性?",了解有关如何发生这种情况的更多信息。简而言之,不要让<T>
欺骗你。
这意味着您不能将DocumentDAO
分配给AbstractDAO<object>
,就像不能将 String 分配给它一样。泛型类型也与继承不同,这似乎是您要实现的目标。
如前所述,在任何一种情况下,都有两种标准解决方案。
首先是在接口上操作。您可以为公共属性创建一个接口,并从中继承AbstractDAO<T>
或任何其他接口。然后大多数时候你只是在接口上操作。具体如何组织它取决于您。
第二种是执行对象的浅拷贝。这意味着将值和引用从一个对象复制到另一个对象。为此,您通常使用像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);
}
默认情况下,自动映射器将映射具有相同名称的字段。您可以为复杂类型映射创建配置。
所以我终于找到了我想要做的答案,而不是将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);
}
}
这样我就可以像这样调用这个函数: 转移<文件>(); 传输<标头>();标头>文件>
等,并进行全面转移
编辑:只是为了完整起见,这是我创建的工厂
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.
}