C#我可以在返回不同泛型类的非泛型类中创建泛型方法或属性吗?

Ing*_*als 3 c# generics methods properties

我有一个抽象的泛型类.我想在那里定义一个方法,所以我不必在所有派生类中都这样做.

基本上我需要根据泛型类的类型来获取一个存储库类.

我通过另一个非泛型的类获取repoistories.

如何让该类根据泛型调用者具有的类型返回通用存储库?

我希望这样的事情.

public IRepository<T> Table<T>()
{
    return _container.Resolve<IRepository<T>>();
}
Run Code Online (Sandbox Code Playgroud)

如果它是一个财产,它会更好.

Ani*_*Ani 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> {  }
Run Code Online (Sandbox Code Playgroud)

用法:

IRepository<Derived> table = new Derived().GetTable();  
Run Code Online (Sandbox Code Playgroud)

但这不是万无一失的.欲了解更多详情,请阅读Eric Lippert 撰写的这篇博客文章:Curiouser和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;     
}
Run Code Online (Sandbox Code Playgroud)