真正的通用实现

时间:2013-08-29 09:06:35

标签: c# .net generics

我用实体框架赢得了表单应用程序。在我的DbContext中,我有两个实例:表;列。在我的dataAccess图层中,我有以下代码

public static class DataLoader
{
    private static WdmEntities _context;

    public static List<T> GetTable<T>() where T : class
       {
           List<T> res = new List<T>();

           using (_context = new WdmEntities())
           {

               try
               {
                   res = _context.Set<T>().ToList();
               }
               catch
               {
               }
           }

           return res;
       }
}

Form.cs我有以下

的事件处理程序
availableTablesListBox.+= availableTablesListBox_SelectedIndexChanged;

void availableTablesListBox_SelectedIndexChanged(object sender, EventArgs e)
{
    //here i need to write code, that call GetTable<T> from DataLoader
    //according to the SelectedIndex of availableTablesListBox
}

但我可以写(不是真正的通用)

if (availableTablesListBox.SelectedIndex == 1) 
     myDataGrid.DataSource = DataLoader.GetTable<tables>();
else 
     myDataGrid.DataSource = DataLoader.GetTable<columns>();

我想写一行代码

myDataGrid.DataSource = DataTable.GetTable<WHAT WRITE HERE>();

2 个答案:

答案 0 :(得分:3)

泛型被纳入IL,因此没有单WHAT WRITE HERE;您必须使用问题中的代码,或者使用基于传递Type实例的非泛型实现。

您可以使用:

myDataGrid.DataSource = availableTablesListBox.SelectedIndex == 1
    ? (IList)DataLoader.GetTable<tables>()
    : (IList)DataLoader.GetTable<columns>();

但那是......不必要的错综复杂。

坦率地说,除了以下内容之外,您当前的实施工作将完成:

  • 不要吞下例外 - catch忽略事情失败的事实只是一个非常糟糕的主意
  • 在这里调用ToList()会强制它加载整个未过滤的表格; 通常一个坏主意

如果要实施基于Type的实施,可以使用非通用Set(Type)方法而不是Set<T>方法。

答案 1 :(得分:1)

应该是这样的:

public static readonly MethodInfo getTableT = ((Func<List<object>>)DataLoader.GetTable<object>)
                                                   .Method
                                                   .GetGenericMethodDefinition();

(使用这些行,我们会在不使用字符串的情况下获得MethodInfo的{​​{1}},而且更加重构

然后

GetTable<T>

你必须使用反射来清楚地表明,因为正如Gravell所说,泛型在编译时得到了解决,因此你无法构建&#34;运行时没有反射的新泛型。