C#通用方法T T类覆盖

时间:2014-06-27 19:25:46

标签: c# entity-framework generics

在C#中,我有一个通用类,如下所示:

public class DataManager<T> : IDisposable where T : class

就像这样使用:

    public T GetById(String id)
    {
        return this.Context.Set<T>().Find(id);
    }

这很有效。

但是如果我在管理器中有两种类型,在这种情况下,Ticket和TicketResponse,我希望能够覆盖该类型而无需在每个方法调用中添加该类型。像这样:

    public T GetById<T>(String id) where T : class
    {
        return this.Context.Set<T>().Find(id);
    }

我可以像这样互换地称呼它:

    var ticket = GetById(myId);
    var ticketResponse = GetById<TicketResponse>(myId); // this would override

我们的想法是不必为子对象创建单独的管理器,也不必让整个票证必须遍历响应,但只能直接获取它。

这可能吗?

4 个答案:

答案 0 :(得分:2)

由于Context.Set允许您指定所需的任何T,因此可以为DataManager类添加接口,添加一个基础类,该基类在基础上下文中公开方法,然后在你的经理类上明确地实现接口:

public interface IDataManager<T> : IDisposable where T : class
{
    T GetById(string id);
}

public class DataManagerBase : IDisposable
{
    protected Find<T>(string id) where T : class
    {
        return this.Context.Set<T>().Find(id);
    }
}

public class TicketManager : DataManagerBase, IDataManager<TicketResponse>, IDataManager<Ticket>
{
    TicketResponse IDataManager<TicketResponse>.GetById(string id)
    {
        return this.Find<TicketResponse>(id);
    }

    Ticket IDataManager<Ticket>.GetById(string id)
    {
        return this.Find<TicketResponse>(id);
    }
}

答案 1 :(得分:1)

您可以尝试这样的事情:

public T GetById( String id )
{
    return GetById<T>( id );
}

public U GetById<U>( String id ) where U : T
{
    return this.Context.Set<U>().Find( id );
}

所以你有原始方法,但也有一个额外的泛型方法,它可以采用另一种派生自T的参数类型。

答案 2 :(得分:0)

如果我理解正确,Ticket是一个特殊情况:Ticket DataManager应该TicketResponse提供方法。这是对的吗?

在这种情况下,您可以将DataManager<T>子类化并添加所需的功能:

class TicketManager : DataManager<Ticket>
{
    public TicketResponse GetResponseById(String id)
    {
        return this.Context.Set<TicketResponse>().Find(id);
    }
}

可以按如下方式使用:

var ticket = myTicketManager.GetById(myId);
var ticketResponse = myTicketManager.GetResponseById(myId);

(如果您担心GetById代码的重复,请将其解压缩为静态受保护的GetByIdInternal<TData>方法。)

答案 3 :(得分:0)

您可以使用封装两个 DataManagers的包装器:

class DataAndResponseManager<TData, TResponse>
{
    private dataManager = new DataManager<TData>();
    private responseManager = new DataManager<TResponse>();

    public TData GetById(String id) { dataManager.GetById(id); }
    public TResponse GetResponseById(String id) { responseManager.GetById(id); }
}

优点:重用所有现有的DataManager代码。

缺点:需要代理方法。