当我实例化某些类的新列表时,我想以某种方式将参数传递给列表。
更具体地说,我想做类似以下的事情:
List<FirstClass>(dataTable);
List<SecondClass>(dataTable);
如果调用第一行代码,构造函数将以某种方式处理dataTable,而不是调用后者(FirstClass有不同的字段)。
我尝试过什么
namespace DeeMacsNamespace
{
public class FirstClass
{
public String Title { get; set; }
public String Url { get; set; }
}
public class FirstClass : List<FirstClass>
{
public FirstClass(DataTable table)
{
foreach (DataRow row in table.Rows)
{
this.Add(new FirstClass()
{
Title = (String)row["Title"]
});
}
}
}
}
我假设(或至少希望),上述方法将起作用。但是,我如何最有效地重用这个代码,该代码从一个非常类似的构造函数中的DataTable
读取某个类的另一个列表?如何合并条件语句来检查构造函数是来自FirstClass
还是SecondClass
类型?我想避免为SecondClass的类似构造函数重写这个。
答案 0 :(得分:1)
如果我理解正确,那么请使用以下内容:
class MyCollection<T> : Collection<T>
{
public MyCollection(DataTable dataTable, Func<DataRow, T> itemsFactory)
: base(dataTable.Rows.Cast<DataRow>().Select(row => itemsFactory(row)).ToList())
{
}
}
var firstClassCollection = new MyCollection<FirstClass>(dataTable, row => new FirstClass
{
Title = (String)row["Title"],
Url = (String)row["Url"]
});
答案 1 :(得分:1)
class FirstClass <T>
{
if (typeof(T) == typeof(FirstClass))
{
// ... snip
}
}
然后让所有其他类继承自FirstClass
。
答案 2 :(得分:1)
关于你的意图有一些未解答的问题。据说这种通用设置可能符合要求:
public interface ISomeInterface
{
String Title { get; set; }
String Url { get; set; }
}
public class SecondClass : ISomeInterface
{
public String Title { get; set; }
public String Url { get; set; }
}
public class FirstClass : ISomeInterface
{
public String Title { get; set; }
public String Url { get; set; }
}
public class SomeClassCollection<T> : List<T> where T: ISomeInterface, new()
{
public SomeClassCollection(DataTable table)
{
foreach (DataRow row in table.Rows)
{
this.Add(new T()
{
Title = (String)row["Title"]
});
}
}
}
private static void Main()
{
var table = new DataTable();
var collection = new SomeClassCollection<FirstClass>(table);
}
答案 3 :(得分:0)
您可以编写扩展方法,例如:
public static class DataTableEx
{
public static IList<T> CreateList<T>(this DataTable dt,
Func<DataRow,T> selector)
{
return dt.Rows.Cast<DataRow>().Select(selector).ToList();
}
}
然后按如下方式使用:
IList<string> myList =
dataTable.CreateList(r => new FirstClass{Title = (string)r["Title"]});
答案 4 :(得分:0)
List<FirstClass> MyList1 = dataTable.Rows.Select(Row =>
new FirstClass()
{
Title = (String)Row["Title"]
}
).ToList();
List<SecondClass> MyList2 = dataTable.Rows.Select(Row =>
new SecondClass() { the way you create second class } ).ToList();
答案 5 :(得分:-1)
首先,您不希望这两个类具有相同的名称(FirstClass和ListOfFirstClass)。
其次,您的问题有点不清楚,但我相信您正在尝试将DataTable转换为First / SecondClass列表。
如果您有权访问DataTable类,则可以让它实现IEnumerable接口。
使用Linq,你可以做类似的事情:
using System.Linq;
public class DataTable : IEnumerable<T>
{
IEnumerable<T> IEnumerable<T>.GetEnumerator()
{
return from row in rows
where FindIfRowIsOfClass<T>(row)
select new T(row);
}
}
您还必须实现通用IEnumerable方法,并填写FindIfRowIsOfClassT方法。这很可能是通过找出它是否具有正确的字段来完成的。
结果是能够做到
List<FirstClass> listOfFirstClass = new List<FirstClass>(dataTable.GetEnumerator<FirstClass>);
我不是百分百肯定,但实际上你可能没有明确地调用GetEnumerator,List可能会为你做这件事。
如果您无权访问,可以手动执行:
var enumerableFirstClass = from row in dataTable.rows
where <insert row is FirstClass check>
select new FirstClass(){Title = (string)row["Title"]};
List<FirstClass> listOfFirstClass = new List<FirstClass>(enumerableFirstClass);
希望这有帮助。
快乐的编码!