C#通用方法可以';t创建列表<;T>;

C#通用方法可以';t创建列表<;T>;,c#,generics,generic-list,C#,Generics,Generic List,我有一个接口和两个类 public interface IMyInterface { } public class A : IMyInterface { } public class B : IMyInterface { } 我有一个通用的方法 private List<T> GetList<T>(DataTable table) where T : class, IMyInterface { ... } private List G

我有一个接口和两个类

public interface IMyInterface { }
public class A : IMyInterface { }
public class B : IMyInterface { }
我有一个通用的方法

private List<T> GetList<T>(DataTable table) 
            where T : class, IMyInterface
{
    ...
}
private List GetList(数据表)
其中T:class,IMyInterface
{
...
}
它将根据DataTable中的数据返回对象列表。所以,我用这个方法创建了一个列表,我想在最后返回它。我想我可以做到以下几点

private List<T> GetList<T>(DataTable table)
           where T : class, IMyInterface
{
   List<T> myList = new List<T>;

   // Now I thought I could easily add Objects based on T because,
   // both classes implement the interface

   if (typeof(T) == typeof(B))
   {
      myList.Add(new B());
   }
   else
   {
      myList.Add(new A());
   }

   return myList;
}
private List<T> GetList<T>(DataTable table)
           where T : class, IMyInterface
{
   List<IMyInterface> myList = new List<IMyInterface>;

   // Now I can assign the Object's :)
   if (typeof(T) == typeof(B))
   {
      myList.Add(new B());
   }
   else
   {
     myList.Add(new A());
   }

   return myList as List<T>;
}
private List GetList(数据表)
其中T:class,IMyInterface
{
列表myList=新列表;
//现在我想我可以很容易地添加基于T的对象,因为,
//这两个类都实现了接口
如果(类型(T)=类型(B))
{
添加(新的B());
}
其他的
{
添加(新的A());
}
返回myList;
}
但是编译器告诉我“参数类型A(B)是不可赋值的”!为什么它不可转让


好的,或者我可以做以下工作

private List<T> GetList<T>(DataTable table)
           where T : class, IMyInterface
{
   List<T> myList = new List<T>;

   // Now I thought I could easily add Objects based on T because,
   // both classes implement the interface

   if (typeof(T) == typeof(B))
   {
      myList.Add(new B());
   }
   else
   {
      myList.Add(new A());
   }

   return myList;
}
private List<T> GetList<T>(DataTable table)
           where T : class, IMyInterface
{
   List<IMyInterface> myList = new List<IMyInterface>;

   // Now I can assign the Object's :)
   if (typeof(T) == typeof(B))
   {
      myList.Add(new B());
   }
   else
   {
     myList.Add(new A());
   }

   return myList as List<T>;
}
private List GetList(数据表)
其中T:class,IMyInterface
{
列表myList=新列表;
//现在我可以指定对象的:)
如果(类型(T)=类型(B))
{
添加(新的B());
}
其他的
{
添加(新的A());
}
返回myList作为列表;
}
编译器没有抱怨,但return子句的结果始终为null。请确保
myList
中有值。演员阵容似乎失败了。请有人帮我更优雅地解决这个问题。

试试这个:

private List<T> GetList<T>(DataTable table) where T : class, IMyInterface {
   List<T> myList = new List<T>();
   if (typeof(T) == typeof(B)) {
      myList.Add((T)new B());
   }
   else {    
     myList.Add((T)new A());
   }
   return myList
}
private List GetList(DataTable表),其中T:class,IMyInterface{
List myList=新列表();
如果(类型(T)=类型(B)){
添加((T)新的B());
}
否则{
添加((T)新的A());
}
返回myList
}

一种方法是添加
new()
约束。限制是您需要为类型参数T使用公共的无参数构造函数

private static List<T> GetList<T>(DataTable table) where T : class, IMyInterface, new()
{
    List<T> myList = new List<T>();
    T instance = new T();
    //access anything defined in `IMyInterface` here
    myList.Add(instance);
    return myList;
}
private static List GetList(DataTable表),其中T:class,IMyInterface,new()
{
List myList=新列表();
T实例=新的T();
//在此处访问“IMyInterface”中定义的任何内容
添加(实例);
返回myList;
}
添加一个

private List GetList(DataTable表),其中T:class,IMyInterface,new()
{
返回新列表(){new T()};
}

我不明白你在这里想干什么。为什么你甚至需要仿制药

最初,您的做法是正确的,从同一个接口派生类型,所以请使用它。声明您的列表
list
,只需按原样添加对象即可


如果以后您确实需要使用具体的
a
B
类型对可枚举对象进行物理表示,您可以使用
of type()
Cast()
来表示它,尽管它首先表明多态性是错误的。

在将对象添加到列表之前,您应该强制转换对象:

 private static List<T> GetList<T>(DataTable table) where T : class, MyInterface
    {
        List<T> myList = new List<T>();

        //Now i thought i can easily add Objects based on T, because both classes
        //implement the interface
        if (typeof (T) == typeof (B))
        {
            // use of 'as' operator
            myList.Add(new B() as T);
        }
        else
        {
            myList.Add(new A() as T);
        }

        return myList;
    }
private static List GetList(DataTable表),其中T:class,MyInterface
{
List myList=新列表();
//现在我想我可以很容易地添加基于T的对象,因为这两个类
//实现接口
如果(类型(T)=类型(B))
{
//“as”运算符的使用
添加(新的B()作为T);
}
其他的
{
添加(新的A()作为T);
}
返回myList;
}
但无论如何,我没有得到一个点,你要达到的目标


另外,
myList as List
肯定会导致
null
,因为
List
未声明为,所以不能使用
as
运算符强制转换泛型集合。您应该显式调用
.Cast()
方法来创建新集合。

仅适用于类A和B

 static List<T> GetList<T>(DataTable table) where T : class, IMyInterface
        {
            List<T> myList = new List<T>();

            IMyInterface obj;
            if (typeof(T) == typeof(B))
            {
                obj = new B();
            }
            else
            {
                obj = new A();
            }

            myList.Add((T)obj);

            return myList;
        }
static List GetList(DataTable表),其中T:class,IMyInterface
{
List myList=新列表();
界面对象;
如果(类型(T)=类型(B))
{
obj=新的B();
}
其他的
{
obj=新的A();
}
myList.Add((T)obj);
返回myList;
}

我猜你真的想做这样的事情

public IList<T> GetList<T>(
        DataTable table,
        Func<DataRow, T> extractor)
{
    var result = new T[table.Rows.Count];
    for (var i = 0; i < table.Rows.Count; i++)
    {
        result[i] = extractor(table.Rows[i]);
    }

    return result;
}

list
将是其他类型中的
IList

您正在查找:
myList.Add((T)Activator.CreateInstance(typeof(T))或围绕这些行的东西。或者转换为
(IMyInterface)
,而不是
(T)
。如果返回泛型或非泛型,则会造成混淆。当您不知道可能使用的类型时,应该使用泛型,但在这里您似乎知道类型是
IMyInterface
@Franck有一种比使用反射更简单的方法,特别是如果它是一个无参数构造函数(请参阅)。我想如果我的类的用户可以命名他想要获得的类型,那将是一件好事。他想要一个有a的列表,所以他直接得到一个列表。但返回列表可能更容易:\n同样,这就是类型()的
的作用。@Sebi Null List?为什么?删除我的评论。我做错了什么事。这与预期一样有效:)