c# - 在 C# 中转换为泛型类型

标签 c# generics

我们在 C# 中有一个抽象泛型类,非常像这样:

public abstract class Repository<T>
    where T: Entity
{
    public abstract void Create(T t);
    public abstract T Retrieve(Id id);
    //etc.
}

我们有一些派生类,例如:

public class EventRepository
    : Repository<Event>
{
    //etc.
}

我们正在实现一个工作单元模式,该模式保留一个字典来将实体类型映射到存储库类型,以便当需要创建或更改实体时,它知道要实例化哪个存储库:

private Dictionary<Type, Type> m_dicMapper;

该字典已初始化并加载所有映射,如下所示:

m_dicMapper.Add(typeof(Event), typeof(EventRepository));
//and so on for a few other repository classes.

然后,当一个实体 e需要创建,例如:

//retrieve the repository type for the correct entity type.
Type tyRepo = m_dicMapper[e.GetType()];
//instantiate a repository of that type.
repo = Activator.CreateInstance(tyRepo);
//and now create the entity in persistence.
repo.Create(e);

问题是,repo是什么类型在上面的代码中?我想将其声明为通用 Repository<T> type,但显然 C# 不允许我这样做。以下行均无法编译:

Repository repo;
Repository<T> repo;
Repository<e.GetType()> repo;

我可以将其声明为 var ,但是我无法访问 Create和其他方法 Repository<T>实现。我希望能够使用通用类来通用地使用存储库!但我想我做错了什么。

所以我的问题是,我可以使用哪些编码和/或设计的解决方法来解决这个问题?谢谢。

最佳答案

我个人建议使用单独的单例类封装对字典的访问,然后包装字典的 getter 和 setter,例如 RepositoryStore类。

我建议更改Dictionary<Type, Type>Dictionary<Type, object> ,然后在 RepositoryStore 内处理转换;像这样吗?

更新(使用 TypeLazy<T> )

如果您使用 .NET 4,您可以充分利用 Lazy class,并将字典类型更改为 IDictionary<Type, Lazy<object>> 。我修改了原来的答案以反射(reflect)它的工作原理:

class RepositoryStore
{
    private IDictionary<Type, Lazy<object>> Repositories { get; set; }

    public RepositoryStore()
    {
        this.Repositories = new Dictionary<Type, Lazy<object>>();
    }

    public RepositoryStore Add<T, TRepo>() where TRepo : Repository<T>
    {
        this.Repositories[typeof(T)] = new Lazy<object>(() => Activator.CreateInstance(typeof(TRepo)));
        return this;
    }

    public Repository<T> GetRepository<T>()
    {
        if (this.Repositories.ContainsKey(typeof(T)))
        {
            return this.Repositories[typeof(T)].Value as Repository<T>;
        }

        throw new KeyNotFoundException("Unable to find repository for type: " + typeof(T).Name);
    }
}

使用方法非常简单...

var repositoryStore = new RepositoryStore()
// ... set up the repository store, in the singleton?

Repository<MyObject> myObjectRepository = repositoryStore.GetRepository<MyObject>();
myObjectRepository.Create(new MyObject());

关于c# - 在 C# 中转换为泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16962687/

相关文章:

c++ - 需要 C++ 中非常通用的 argmax 函数

javascript - 为什么我从 c# 到 js 得到不同的 MD5 哈希值?

c# - 提示用户许可 - facebook 开发人员工具包

c# - 解析方法重载时有优先级吗?

c# - 泛型方法,使用where T : base. 为什么调用其他方法时不认为T是具体类型?

Java继承多级层次结构中的Fluent方法返回类型

c# - C#中的匿名方法是什么?

c# - 公开多个数据绑定(bind)源

c# - .NET 文件访问冲突

java - 将泛型对象数组转换为另一个泛型类的数组