从类创建动态数据表和数据行
本文关键字:数据 数据表 动态 创建 | 更新日期: 2023-09-27 18:31:00
我有许多不同大小和类型的类,我正在尝试获取一个通用脚本来填充它们。
请考虑以下代码。 我遇到的问题是最后它只打印列名(正确),但没有值。
在逐步执行代码时,我可以看到它认为我在createDataRow方法中传递的类型是空的,我不明白为什么。
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"函数。
我做错了什么?
我被舔了!
所以诀窍在于 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();
}
}
为什么需要这个函数?
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
}
}