从类创建动态DataTable和DataRow

时间:2013-09-12 10:46:31

标签: c# class generics methods types

我有许多不同大小和类型的类,我正在尝试使用通用脚本来填充它们。

请考虑以下代码。我遇到的问题是,最后它只打印列名(正确)但没有值。

虽然单步执行代码我可以看到它认为我在createDataRow方法中传递的Type是空的,我不明白为什么。

public class tables { }
public class Dog : tables
{
    public string Breed { get; set; }
    public string Name { get; set; }
    public int legs { get; set; }
    public bool tail { get; set; }
}



class Program
{
    public static DataTable CreateDataTable(Type animaltype)
    {
        DataTable return_Datatable = new DataTable();
        foreach (PropertyInfo info in animaltype.GetProperties())
        {
            return_Datatable.Columns.Add(new DataColumn(info.Name, info.PropertyType));
        }
        return return_Datatable;
    }

    public static DataRow createDataRow(tables dog, DataTable touse) //This is half of the problem
    {
        Type type = dog.GetType();
        DataRow x = touse.NewRow();

        foreach (PropertyInfo prop in typeof(tables).GetProperties()) //this is the other half of the problem
        {
            x[prop.Name] = prop.GetValue(dog, null);
        }

        return x;
    }

    static void Main(string[] args)
    {
        Dog Killer = new Dog();
        Killer.Breed = "Maltese Poodle";
        Killer.legs = 3;
        Killer.tail = false;
        Killer.Name = "Killer";

        DataTable dogTable = new DataTable();
        dogTable = CreateDataTable(typeof(Dog));
        DataRow dogRow = dogTable.NewRow();
        dogRow = createDataRow(Killer, dogTable); //This is where I pass the data
        dogTable.Rows.Add(dogRow);

        foreach (DataRow row in dogTable.Rows)
        {
            foreach (DataColumn col in dogTable.Columns)
            {
                Console.WriteLine("Column {0} =" + row[col].ToString(),col.ColumnName);
            }
        }
        Console.ReadLine();

    }      
}

现在,如果我要更改以下内容:

 public static DataRow createDataRow(tables dog, DataTable touse)

 public static DataRow createDataRow(Dog dog, DataTable touse)

foreach (PropertyInfo prop in typeof(tables).GetProperties())

foreach (PropertyInfo prop in typeof(Dog).GetProperties())

......一切正常。
但我不想这样做,因为这意味着我必须为我的每个类创建一个“createDataRow”函数,我有数百个。

我做错了什么?

2 个答案:

答案 0 :(得分:1)

我舔了舔!

因此,诀窍是在CreateDataRow方法中将类作为对象传递。

namespace Generics

{

public class Dog
{
    public string Breed { get; set; }
    public string Name { get; set; }
    public int legs { get; set; }
    public bool tail { get; set; }   

}

public class Cat
{
    public string Breed { get; set; }
    public string Name { get; set; }
    public int toes { get; set; }
    public bool Aggressive { get; set; }
    public bool tail { get; set; }
}



class Program
{


    public static DataTable CreateDataTable(Type animaltype)
    {

        DataTable return_Datatable = new DataTable();
        foreach (PropertyInfo info in animaltype.GetProperties())
        {
            return_Datatable.Columns.Add(new DataColumn(info.Name, info.PropertyType));
        }
        return return_Datatable;
    }


    public static DataRow makeRow(object input, DataTable table)
    {
        Type inputtype = input.GetType();
        DataRow row = table.NewRow();
        foreach (PropertyInfo info in inputtype.GetProperties())
        {
            row[info.Name] = info.GetValue(input, null);
        }
        return row;
    }

    static void Main(string[] args)
    {
        Cat Dexter = new Cat();
        Dexter.Breed = "Bengal";
        Dexter.toes = 12;
        Dexter.tail = false;
        Dexter.Name = "Killer";
        Dexter.Aggressive = true;

        Dog Killer = new Dog();            
        Killer.Breed = "Maltese Poodle";
        Killer.legs = 3;
        Killer.tail = false;
        Killer.Name = "Killer";       

        DataTable dogTable = CreateDataTable(typeof(Dog));
        dogTable.Rows.Add(makeRow(Killer, dogTable));

        DataTable catTable = CreateDataTable(typeof(Cat));
        catTable.Rows.Add(makeRow(Dexter, catTable));


        foreach (DataRow rows in catTable.Rows)
        {
            foreach (DataColumn col in catTable.Columns)
            {
                Console.WriteLine("Column {0} =" + rows[col].ToString(), col.ColumnName.PadRight(15));
            }
        }


        foreach (DataRow rows in dogTable.Rows)
        {
            foreach (DataColumn col in dogTable.Columns)
            {
                Console.WriteLine("Column {0} =" + rows[col].ToString(),col.ColumnName.PadRight(15));
            }
        }
        Console.ReadLine();

    }      
}

答案 1 :(得分:0)

为什么需要这个功能?

public static DataRow createDataRow(Dog dog, DataTable touse)

Dog派生自表格,因此您可以使用:

public static DataRow createDataRow(tables dog, DataTable touse)

如果你有不同的实现,你可以覆盖基本方法,但在这种情况下你必须使它成为虚拟(并在基类中声明基本方法):

public virtual DataRow createDataRow(DataTable touse)

如果你想享受多态性的好处,不要让它静止。

您不必传递表实例,只需调用实例:

tables foo = new Dog();
var dr = foo.createDataRow(return_Datatable);

类:

public class tables 
{ 
    public virtual DataRow createDataRow(DataTable touse)
    {
       //base implementation
    }

}

public class Dog : tables
{
    public string Breed { get; set; }
    public string Name { get; set; }
    public int legs { get; set; }
    public bool tail { get; set; }
    public override DataRow createDataRow(DataTable touse)
    {
       //derived implementation
    }
}