【问题标题】:Dynamically create and set members/properties of class at runtime在运行时动态创建和设置类的成员/属性
【发布时间】:2014-01-03 17:25:10
【问题描述】:

如何在运行时动态创建和设置类的成员/属性。

参考:http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.trygetmember(v=vs.110).aspx

我试图修改想法以适应我的要求,但无法做到。

我需要在运行时设置类成员,这意味着我将从数据库中获取KeyValue,我的类将是完全动态的,在运行时之前没有定义任何成员,但所有这些都是从运行时的数据库。

这是我的代码(取自 MSDN):

public class DynamicObjDictionary : DynamicObject
{
    // The inner dictionary.
    Dictionary<string, object> dictionary = new Dictionary<string, object>();
    public int Count
    {
        get{return dictionary.Count;}
    }

public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        string name = binder.Name.ToLower();
        return dynDict.TryGetValue(name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        dynDict[binder.Name.ToLower()] = value;
        return true;
    }
 }
}

初始化和定义类的成员/属性的代码

dynamic DynObj = new DynamicObjDictionary();
        DataSet ds = new DataSet();
        ds = GetObjectProperties() // returns dataset having the properties as key and value pair;
        if (ds.Tables["PropTable"].Rows.Count > 0)
        {
            foreach (DataRow dr in ds.Tables["PropTable"].Rows)
            {
                string KeyName = dr["KeyName"].ToString();
                string ValueName= dr["ValueName"].ToString();
                //---I want that in place of fldName the actual value from dr is added to the class - currently it returns DynObj.KeyName only.
                DynObj.KeyName = ValueName;
                // Means if current dr["KeyName"].ToString() has "Property1"
                // And dr["ValueName"].ToString() has "PropertyValue"
                // The DynObj should be like DynObj.Property1 = "PropertyValue" 
            }
        }

另一个问题是我希望在上述初始化之后设置所有属性,以便我可以像硬编码的类对象一样访问它们。当前代码仅零售最后一个属性,即数据集最后一行的值。

【问题讨论】:

  • 为什么不使用 ExpandoObject ?
  • 如果你这样做,你以后将如何访问这些属性?然后你需要知道 KeyName,但如果你已经知道了,为什么不直接使用字典呢?
  • 所有值都是字符串?
  • @DanielHäfele,该类将是可序列化的,并将用于为 web 服务返回 json,因此,知道 KeyName 不是问题。
  • @Cyber​​pks 那么为什么不直接使用裸字典呢?如果您将字典传递给大多数 json 序列化程序,它们就会确切地知道您的意思......

标签: c# class oop dynamic


【解决方案1】:

要么添加基于字典的 API,要么使用已有的实现。坦率地说,ExpandoObject 可以正常工作,并且内置了 IDictionary&lt;string,object&gt; API。

var obj = new ExpandoObject();
DataSet ds = GetObjectProperties() // returns dataset having the properties as key and value pair;
if (ds.Tables["PropTable"].Rows.Count > 0)
{
    foreach (DataRow dr in ds.Tables["PropTable"].Rows)
    {
        string KeyName = dr["KeyName"].ToString();
        string ValueName= dr["ValueName"].ToString();
        obj[KeyName] = ValueName;
    }
}
dynamic DynObj = obj;
// ...

【讨论】:

  • 感谢您的回答和上述建议。我必须实际使用ExpandoObject() 来维护Key-Value 对,然后将数据作为动态返回。
  • @marc:我试过你的代码,但这一行给出错误 obj[KeyName] = ValueName;我正在使用VS2010。任何帮助。
  • @Thomas 啊,我完全有可能在“手机!您可能需要将 obj 转换为 IDictionary&lt;string,object&gt; 才能访问索引器
  • 是的。绝对必须强制转换 ExpandoObject: ((IDictionary)obj)[KeyName] = ValueName;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-08
  • 2017-04-27
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多