我想将参数传递给某些类列表的构造函数

时间:2013-05-07 20:13:24

标签: c# list generics methods constructor

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

更具体地说,我想做类似以下的事情:

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的类似构造函数重写这个。

6 个答案:

答案 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);

希望这有帮助。

快乐的编码!