类中的通用方法

时间:2013-08-28 11:19:51

标签: c# .net generics type-conversion

我的代码:

public class MyClass
{
    private WdmEntities _context;

    public List<T> GetTable<T>()
    {
        List<T> res = new List<T>();
        _context = new DbEntities();

        if (typeof(T) == typeof(tables))
            res = _context.tables.ToList();//error cannot implicitly convert type
        if (typeof(T) == typeof(columns))
            res = _context.columns.ToList();//error cannot implicitly convert type

        return res;
    }

}

我有来自 EntityModel

的表格和列类型

但是我收到了编译错误:

 cannot implicitly convert type

我必须如何更改代码才能使其正常工作?

3 个答案:

答案 0 :(得分:5)

您需要投射每个项目:

public class MyClass
{
    private WdmEntities _context;

    public List<T> GetTable<T>()
    {
        List<T> res = new List<T>();
        _context = new DbEntities();
        if (typeof(T) == typeof(tables))

            // If the defined entity type is an abstract class or interface
            // while the returned type from the dbcontext really is of your object type
            res = _context.tables.Cast<T>().ToList();
        if (typeof(T) == typeof(columns))
            res = _context.columns.Cast<T>().ToList();

        return res;
    }

}

或只是收藏:

public class MyClass
{
    private WdmEntities _context;

    public List<T> GetTable<T>()
    {
        List<T> res = new List<T>();
        _context = new DbEntities();
        if (typeof(T) == typeof(tables))

            //Just casting the returned list, if the entity type is the same as T
            res = (List<T>)_context.tables.ToList();
        if (typeof(T) == typeof(columns))
            res = (List<T>)_context.columns.ToList();

        return res;
    }

}

..取决于您的上下文的创建方式。

答案 1 :(得分:5)

在这样的一行:

    if (typeof(T) == typeof(tables))
        res = _context.tables.ToList();

编译器不会尝试理解此if测试如何影响分配规则;就你而言,你试图将List<table>分配给List<T>,并且不正常,因为编译器不相信你{ {1}} === table

你可以使用强制转换强制

T

但是,您可能想要检查 if (typeof(T) == typeof(tables)) res = (List<T>)(object)_context.tables.ToList(); 是否具有通用API。例如,在LINQ-to-SQL中:

_context

在一个不相关的说明中:在未经过滤的表格上调用res = _context.GetTable<T>().ToList(); 通常是一件非常糟糕的事情。

因此,最好返回ToList()或ORM首选的IQueryable<T>包装器。例如,使用LINQ-to-SQL,可能是:

IQueryable<T>

或使用实体框架:

public Table<T> GetTable<T>()
{
    return ctx.GetTable<T>();
}

但是,您还应该仔细考虑数据上下文的生命周期管理;在问题的代码中,你public DbDet<T> GetTable<T>() { return ctx.Set<T>(); } 数据上下文 - 这个上下文然后是自由浮动的,并且没有被我认为是可接受的方式清理。你应该考虑更多的终身管理。

答案 2 :(得分:4)

您可以在此处使用Cast方法。

if (typeof(T) == typeof(tables))
    res = _context.tables.Cast<T>().ToList();
if (typeof(T) == typeof(columns))
    res = _context.columns.Cast<T>().ToList();

然而,这看起来不是一个好的通用方法。当您需要返回另一种类型的列表时,您将不得不更改代码。您应该找到一种方法,使用另一种通用方法从上下文中获取项目。如果那是不可能的,我建议放弃泛型方法并为这些类型编写两个单独的方法。