简体   繁体   English

泛型 - 使用父类指定泛型中的类型

[英]Generics - Using parent class to specify type in generics

I am looking at some covariance/contravariance stuff, I have a much wider question but it all boils down to this: 我正在研究一些协方差/逆变问题,我有一个更广泛的问题,但这一切归结为:

GenericRepository<BaseEntity> repo = new GenericRepository<ProductStyle>(context);

This doesn't work, even though BaseEntity is the parent abstract class of ProductStyle, is there a way of achieving this? 这不起作用,即使BaseEntity是ProductStyle的父抽象类,有没有办法实现这一点?

The only way of doing that is with an out generic restriction (which will make it hard to save objects, but fine to retrieve them), on an interface (not a class ). 这样做的唯一方法是在interface (不是class )上使用out通用限制(这将使得很难保存对象,但很难检索它们)。 If you have: 如果你有:

interface IGenericRepository<out T> {...}

then an IGenericRepository<ProductStyle> can be assigned to a variable of type IGenericRepository<BaseEntity> , since all ProductStyle are also BaseEntity , and we have restricted ourselves to covariant / out usage: 然后可以将IGenericRepository<ProductStyle>分配给IGenericRepository<BaseEntity>类型的变量,因为所有ProductStyle也是BaseEntity ,并且我们限制自己使用协变/ out

IGenericRepository<BaseEntity> tmp = GetRepo<ProductStyle>(context);
// note that the right-hand-side returns IGenericRepository<ProductStyle>
...
private IGenericRepository<T> GetRepo(...) {...}

Note, however, that this covariant / out usage makes it impossible to do things like: 但请注意,这种协变/ out使用使得无法执行以下操作:

interface IGenericRepository<out T>
{
    T Get(int id); // this is fine, but:
    void Save(T value); // does not compile; this is not covariantly valid
}

I'm just wondering if something like this would also be useful -- using a restriction on the definition of your GenericRepository limiting the base type that T can be: 我只是想知道这样的事情是否也会有用 - 使用对GenericRepository定义的限制来限制T可以是的基类型:

void Main()
{
    var repo = new GenericRepository<ProductStyle>(new ProductStyle());
    Console.WriteLine(repo.ToString());  //just output something to make sure it works...
}

// Define other methods and classes here
public class GenericRepository<T> where T : BaseEntity {
    private readonly T _inst;

    public GenericRepository(T inst){
        _inst = inst;
        _inst.DoSomething();
    }
}

public class BaseEntity {
    public Int32 Id {get;set;}

    public virtual void DoSomething() { Console.WriteLine("Hello"); }
}

public class ProductStyle : BaseEntity {
}

So if you have a GetRepo<T> method, that method could return a GenericRepository of T, and you're assured that T is a child of BaseEntity . 因此,如果您有一个GetRepo<T>方法,该方法可以返回T的GenericRepository,并且您确信TBaseEntity的子级。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM