0

当我实例化某些类的新列表时,我想以某种方式将参数传递到列表中。

更具体地说,我想做如下的事情:

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一个非常相似的构造函数中读取的代码,用于某个类的另一个列表?以及如何合并条件语句来检查构造函数是否来自FirstClassorSecondClass类型?我想避免为 SecondClass 的类似构造函数重写它。

4

6 回答 6

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"]
});
于 2013-05-07T20:20:06.910 回答
1
class FirstClass <T>
{
  if (typeof(T) == typeof(FirstClass))
  {
    // ... snip
  }
}

然后让所有其他类继承自FirstClass.

于 2013-05-07T20:24:00.380 回答
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);
    }
于 2013-05-07T20:28:57.377 回答
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"]});
于 2013-05-07T20:27:46.177 回答
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();
于 2013-05-07T20:28:56.950 回答
-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>);

我不是 100% 确定,但你实际上可以不显式调用 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);

希望这可以帮助。

快乐编码!

于 2013-05-07T20:34:28.007 回答