我正在编写一个函数,其中给了DataTable
,该函数应该识别类型并将数据表转换为其类型的列表。但是我的问题是,每当我返回列表时,都会出现错误:
无法隐式转换类型
'System.Collections.Generic.List<ADMPortal_2.Modles.ProductionPending>'
到
'System.Collections.Generic.List<T>'
现在如何创建一个可以返回任何类型的list<>
的函数?
例如
List<ProductionPending>
List<ProductionRecent>
List<MirrorDeployments>
功能
public List<T> ConvertToList<T>(DataTable dt, int listType)
{
if (listType == 1)
{
List<ProductionPending> list = new List<ProductionPending>();
list = ConvertToProductionPending(dt);
return list;
}
else if (listType == 2)
{
List<ProductionRecent> list = new List<ProductionRecent>();
ConvertToProductionRecent(dt);
return list;
}
else if (listType == 3)
{
List<MirrorDeployments> list = new List<MirrorDeployments>();
list = ConvertToMirror(dt);
return list;
}
return list;
}
调用函数
以下代码是调用上述函数的经典方法。
using (OracleConnection conn = new OracleConnection(cnnStr))
{
using (OracleCommand objCommand = new OracleCommand(strSql, conn))
{
objCommand.CommandType = CommandType.Text;
DataTable dt = new DataTable();
OracleDataAdapter adp = new OracleDataAdapter(objCommand);
conn.Open();
adp.Fill(dt);
if (dt != null)
{
list = ConvertToList<T>(dt, 1).ToList();
}
}
}
答案 0 :(得分:2)
您的方法存在的问题是您的类型没有太多共同之处。仅由于某个类具有某种继承关系,并不意味着该类的列表具有相同的关系。换句话说:List<Derived>
不能转换为List<Base>
。
如果List<T>
是协变的,则可以实现此目的-并非出于以下原因。假设您的ConvertToList
方法的客户做了这样的事情:
var list = ConvertToList<MyBaseClass>(theTable, 1)
现在您还可以执行以下操作:
list.Add(new ProductionRecent());
这可能不是您想要的。因此,您需要一些只读的集合,这意味着您无法向其添加实例。因此IEnumerable<T>
接口 是协变的,可以用作您方法的返回类型。
答案 1 :(得分:0)
IEnumerable在其通用类型中使用out
关键字,因此您可以使用派生类型作为回报。那么这样的事情呢?
public static IEnumerable<IBase> ConvertToList(int listType)
{
if (listType == 1)
{
var list = new List<ClassA>();
...
return list;
}
if (listType == 2)
{
var list = new List<ClassB>();
...
return list;
}
if (listType == 3)
{
var list = new List<ClassC>();
...
return list;
}
return null;
}
}
public class ClassA : IBase
{ }
public class ClassB : IBase
{ }
public class ClassC : IBase
{ }
public interface IBase
{ }
答案 2 :(得分:0)
正如您所说的,它们有一个共同的基类:
public List<CommonBaseClass> ConvertToList(DataTable dt, int listType)
{
var result = List<CommonBaseClass>();
if (listType == 1)
{
result.AddRange(ConvertToProductionPending(dt));
}
else if (listType == 2)
{
result.AddRange(ConvertToProductionRecent(dt));
}
else if (listType == 3)
{
result.AddRange(ConvertToMirror(dt));
}
return result;
}