【问题标题】:Set PropertyName using variable value使用变量值设置 PropertyName
【发布时间】:2012-03-29 06:39:38
【问题描述】:

我想创建一个类的属性,并使用变量值设置该属性的名称。

例如

string resultValue = "stack"; 
MyClass myclass = new MyClass();
myclass.resultValue = "overflow";

现在在这种情况下,stack 是属性名称,"overflow"stack 属性的值。

请告诉怎么可能。

提前致谢。

【问题讨论】:

  • 你为什么要生成属性?

标签: c# reflection


【解决方案1】:

您可以使用Reflection。例如:

string name = "stack";
string value = "overflow";
PropertyInfo pi = typeof(MyClass).GetProperty(name);
MyClass instance = new MyClass();
pi.SetValue(instance, value, null);
// at this stage instance.stack equals to "overflow"

这显然假设MyClass 有一个带有公共设置器的公共属性堆栈:

public class MyClass
{
    public string stack { get; set; }
}

【讨论】:

  • instance.stack = value 有什么区别?
  • 不同之处在于你不必在编译时知道变量的名称。
  • 不管怎样,取名后需要查看pi != null
  • 奇怪.. 问题是关于生成属性,而不是关于按名称访问。
【解决方案2】:

你应该为此使用反射

MyClass myclass = new MyClass();
Type type = typeof(MyClass);
PropertyInfo property = type.GetProperty("stack");
property.SetValue(myclass, "overflow", null);

【讨论】:

    【解决方案3】:

    我认为 MSDN 上的Dynamic Source Code Generation and Compilation 部分应该包含您需要的信息。

    .NET Framework 包含一种称为代码文档的机制 对象模型 (CodeDOM),使开发人员能够发出 源代码生成多种编程语言的源代码 在运行时,基于代表代码的单个模型 渲染。

    我认为您也可以使用 Reflection 完成此操作。

    【讨论】:

      【解决方案4】:

      也许你应该看看DynamicObject。有了这个,您可以通过简单地分配一个值在运行时创建属性。也可以在MSDN article 找到一个示例。

      【讨论】:

        【解决方案5】:

        看看 Mark Gravell 的FastMember

        它允许您以动态方式设置属性。

        // obj could be static or DLR 
        var wrapped = ObjectAccessor.Create(obj); 
        string propName = // something known only at runtime 
        

        FastMember Blog Post

        【讨论】:

          【解决方案6】:

          我无法想象您为什么要在类上生成属性,但请考虑其他方式。例如。使用Dictionary:

          class MyClass
          {
              Dictionary<string, object> _values = new Dictionary<string, object>();
          
              public object this[string name]
              {
                  get
                  {
                      if (!_values.ContainsKey(name))
                          throw new ArgumentException(name);
          
                      return _values[name];
                  }
          
                  set
                  {
                      if (!_values.ContainsKey(name))
                      {
                          _values.Add(name, value);
                          return;
                      }
          
                      _values[name] = value;
                  }
              }
          }
          

          用法:

          MyClass myClass = new MyClass();
          myClass["stack"] = "overflow";
          Console.WriteLine(myClass["stack"]);
          

          【讨论】:

          • 您可以跳过set 方法中的整个if 子句,因为_values[name] = value 会在不存在时添加密钥。
          • @ChrisWue 谢谢,忘了!
          【解决方案7】:

          据我所知,这是不可能的。您可以尝试使用字典。

          【讨论】:

          • @hamad 也许 Mariusz 不知道反射,那么他没有撒谎! :)
          • @Bazzz :) 那么没有研究和正确理解的人不应该回复
          猜你喜欢
          • 1970-01-01
          • 2023-03-31
          • 2012-04-27
          • 2011-12-29
          • 1970-01-01
          • 1970-01-01
          • 2012-03-01
          • 1970-01-01
          • 2015-09-11
          相关资源
          最近更新 更多