【问题标题】:Create property at runtime在运行时创建属性
【发布时间】:2012-09-19 19:29:40
【问题描述】:

是否可以在运行时为类型创建属性?我的类型“Account”有一组预定义的属性,例如“ID”和“Account Name”,它实现了 INotifyPropertyChanged,我想在运行时向这个类型添加属性,所以 getter 和 setter 和 setter 会调用一个方法通知传入它的属性名称,即

public string Name
{
     get { return _name; }
     set
     {
          _name = value;
          NotifyPropertyChanged("Name");
     }
}

【问题讨论】:

  • 你想完成什么?你想重新发明DataTable吗?
  • 基本上,我正在从数据存储区发送数据,我得到一个固定的列数据包和一个变化的数据包。不知道如何处理不同的数据包。
  • 您使用的是什么版本的 .Net?
  • 在运行时创建属性的目的是什么?您将需要(再次)使用反射来使用它们,因为在编译时它们将不存在。

标签: c#


【解决方案1】:

是的,但不是“正常”CLR 类型。您可以实现这一点,实际上该类型是专门为此类功能创建的:DynamicObject

查看实现DynamicObject的类提供的示例代码,例如

public class DynamicDictionary : DynamicObject
{
   ...
}

在你能够像这样使用它之后:

dynamic person = new DynamicDictionary();

// Adding new dynamic properties.      
person.FirstName = "Ellen";
person.LastName = "Adams";

【讨论】:

【解决方案2】:

您可以使用Reflection.Emit 动态创建从您的类继承的新类,然后将属性添加到该新类型。 由于它继承了您自己的类型,因此可以将其视为该类型的“扩展”。

我必须警告你,这条路很复杂,你可能会在完成工作后产生永远不会再理解的代码!

此外,您将了解 MSIL 代码的工作原理。这有点奇怪,而且是颠倒的。您必须以与 C# 等语言所期望的完全相反的方式做事。您必须从堆栈中推送和弹出值以作为参数传递给函数,并且您必须主动丢弃函数中未使用的返回值......等等。

是的,我想让你害怕这个......这是一种痛苦的方式;)

在选择这个之前考虑其他替代方案。

SO 中已经有很多关于这个问题的材料:https://stackoverflow.com/questions/tagged/reflection.emit

解释 Reflection.Emit 的 CodeProject 文章: Dynamic Type Using Reflection.Emit

【讨论】:

【解决方案3】:

要么使用动态对象,要么通过扩展方法扩展行为。我不知道其他选项。

【讨论】:

    【解决方案4】:

    不,这对于 c# 对象是不可能的

    你可以像类一样制作字典,它可以存储不同的属性,比如使用 DynamicObject 的问题

    你可以做的是通过反射创建新的类类型,它们可以包含新的属性。但是没有简单的方法可以访问这些

    【讨论】:

    • 如果您不赞成,请添加 cmets,答案是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 2018-08-05
    • 2017-09-02
    • 2012-04-08
    • 1970-01-01
    相关资源
    最近更新 更多