我有一个抽象的泛型类。我想在那里定义一个方法,所以我不必在所有派生类中都这样做。
基本上我需要根据泛型类的类型获取一个存储库类。
我通过另一个非通用的类来获取repoistories。
如何让该类根据通用调用者的类型返回通用存储库?
我希望有这样的事情。
public IRepository<T> Table<T>()
{
return _container.Resolve<IRepository<T>>();
}
如果它是一个财产,它会更好。
答案 0 :(得分:6)
C#无法表达“自我”类型,但您可以使用奇怪的重复模板模式(CRTP)模拟。
public class Base<TSelf> where TSelf : Base<TSelf>
{
// Make this a property if you want.
public IRepository<TSelf> GetTable()
{
return _container.Resolve<IRepository<TSelf>>();
}
}
public class Derived : Base<Derived> { }
用法:
IRepository<Derived> table = new Derived().GetTable();
但这不是万无一失的。有关更多详细信息,请阅读Eric Lippert撰写的这篇博客文章:Curiouser and curiouser。
另一方面,如果您只需要_container.Resolve
调用的类型参数基于当前类型,但可以从该方法返回更通用的类型,则不必诉诸这种模式。您可以改为使用反射:
// If the container's Resolve method had an overload that
// accepted a System.Type, it would be even easier.
public SomeBaseType GetTable()
{
var repositoryType = typeof(IRepository<>).MakeGenericType(GetType());
var result = _container.GetType()
.GetMethod("Resolve")
.MakeGenericMethod(repositoryType)
.Invoke(_container, null);
return (SomeBaseType) result;
}
答案 1 :(得分:1)
我没有看到问题。你可以编写这样编译的代码。这不能达到你想要的效果吗?
interface IRepository<T>
{
T GetData();
}
class Container
{
private object[] data = null;
public T Resolve<T>()
{
return(T)data.First(t => t.GetType() is T);
}
}
abstract class Handler<T>
{
private Container _container;
public IRepository<T> Table
{
get
{
return _container.Resolve<IRepository<T>>();
}
}
}