在运行时设置类的属性
本文关键字:属性 设置 运行时 | 更新日期: 2023-09-27 18:34:50
我正在尝试在 C# 中实现这样的事情:
public class GenericModel
{
public SetPropertiesFromDataRow(DataColumnCollection columns, DataRow row)
{
foreach(DataColumn column in columns)
{
this.SetProperty(column.ColumnName, row[column.ColumnName]);
}
}
}
DataTable students = ReadStudentsFromDatabase(); // This reads all the students from the database and returns a DataTable
var firstStudent = new GenericModel();
firstStudent.SetPropertiesFromDataRow(students.Columns, students.Rows[0]);
这在 C# 中是否可以做到(因为它是一种静态语言(?
(请注意,此示例是某种伪代码。
以下是使用 ExpandoObject 的示例
dynamic eo = new ExpandoObject();
var dic = eo as IDictionary<string, object>;
foreach (string propertyName in XXX)
{
dic[propertyName] = propertyValue;
}
当然,这是可能的。C# 具有反射系统,可让您在运行时检查类结构并设置类元素。例如,当您在string
中只有一个名称时,要在this
上设置属性,可以按以下步骤完成:
foreach(DataColumn column in columns) {
PropertyInfo prop = GetType().GetProperty(column.Name);
prop.SetValue(this, row[column.Name]);
}
这假设了几件事:
DataColumn
对象的名称与类中的属性名称(包括大小写(完全匹配- 类型中没有缺少任何
DataColumn
s,即如果存在列Xyz
则类中必须有一个属性Xyz
- 从数据表中读取的对象数据类型与其相应属性的类型赋值兼容。
如果这些要求中的任何一个被破坏,就会出现运行时错误。您可以在代码中解决它们。例如,如果您希望使其在通用模型可能缺少某些属性的情况下工作,请对prop
变量添加null
检查,并在看到prop ==null
时跳过对SetValue
的调用。
您可以使用反射来执行此操作,例如
objName.GetType().GetProperty("nameOfProperty").SetValue(objName, objValue, null)
使用动态变量设置动态属性,如下所示:
class Program{
static void Main(string[] args)
{
dynamic x = new GenericModel();
x.First = "Robert";
x.Last = " Pasta";
Console.Write(x.First + x.Last);
}
}
class GenericModel : DynamicObject
{
Dictionary<string, object> _collection = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _collection.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_collection.Add(binder.Name, value);
return true;
}
}
请参考链接:MSDN