在运行时设置类的属性

时间:2014-12-20 08:06:23

标签: c# .net

我想在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#做​​(因为它是一种静态语言)? (请注意,此示例是某种psudocode。)

4 个答案:

答案 0 :(得分:1)

以下是使用ExpandoObject

的示例
dynamic eo = new ExpandoObject();
var dic = eo as IDictionary<string, object>;
foreach (string propertyName in XXX)
{
    dic[propertyName] = propertyValue;
}

答案 1 :(得分:0)

当然,这是可能的。 C#具有反射系统,可以让您检查类结构并在运行时设置类元素。例如,要在this上设置属性,只需拥有string中的名称即可,如下所示:

foreach(DataColumn column in columns) {
    PropertyInfo prop = GetType().GetProperty(column.Name);
    prop.SetValue(this, row[column.Name]);
}

这假定了几件事:

  • DataColumn个对象的名称与您班级中的属性名称完全匹配,包括大写
  • 类型中没有DataColumn个缺失,即如果列Xyz,则类中必须有属性Xyz
  • 从数据表中读取的对象的数据类型与其相应属性的类型分配兼容。

如果这些要求中的任何一个被破坏,就会出现运行时错误。您可以在代码中解决它们。例如,如果您希望在通用模型可能缺少某些属性的情况下使其工作,请在null变量上添加prop检查,并在您启动时跳过对SetValue的调用见prop ==null

答案 2 :(得分:0)

您可以使用Reflection来执行此操作,例如

objName.GetType().GetProperty("nameOfProperty").SetValue(objName, objValue, null)

答案 3 :(得分:0)

使用动态变量设置动态属性,如下所示:

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