简体   繁体   English

NET中如何在运行时向对象添加属性?

[英]How to add properties to the object at run-time in .net?

I'm using a 3rd party lib to do some work. 我正在使用3rd party lib做一些工作。 I'm passing an object to the lib and it performing some actions on each property of the object. 我将一个对象传递给lib,它对对象的每个属性执行一些操作。 It enumerates properties using reflection. 它使用反射枚举属性。 This is how it implemented and I can't change it. 这是它的实现方式,我无法更改。

I don't know which and how many properties should be processed by the lib at compile-time. 我不知道在编译时lib应该处理哪些属性以及多少属性。 This information only available at run-time. 此信息仅在运行时可用。 So I can't create class declaration in my source code. 因此,我无法在源代码中创建类声明。

It seems dynamic feature of .net4 can't help me because lib using reflection, not dynamic. .net4的dynamic功能似乎无济于事,因为lib使用反射而不是动态的。

Actually I can see only two options here: 实际上,我在这里只能看到两个选项:

  1. Create a huge class definition like this: 创建一个巨大的类定义,如下所示:

     class Data { public object P1 {get; set;} public object P2 {get; set;} .... public object PN {get; set;} // N should be at least 10.000 } 
  2. Generate class definition at runtime and use CSharpCodeProvider to compile an use it. 在运行时生成类定义,并使用CSharpCodeProvider进行编译。

Can you suggest me any other options? 您能建议我其他选择吗?

And sadly, I can't replace this lib with another one. 可悲的是,我不能用另一个库代替这个库。

Using the first approach will lead to high memory consumption. 使用第一种方法将导致高内存消耗。 I would have chosen use TypeBuilder class to create new types at the runtime. 我会选择使用TypeBuilder类在运行时创建新类型。

What you're looking for is known as a Property Bag . 您要寻找的东西被称为“ 物业袋” You may be able to implement something like this by using ICustomTypeDescriptor to expose additional metadata (assuming your library supports it). 您可以使用ICustomTypeDescriptor公开其他元数据(假设您的库支持它)来实现类似的功能。

If your consuming library is using Reflection directly (and not taking advantage of designer features like Type Descriptors) then your best bet is probably dynamic generation of a proxy wrapper with the additional properties. 如果您的使用库直接使用了Reflection(而不利用类型描述符等设计器功能),那么最好的选择可能是动态生成具有其他属性的代理包装器。 Castle DynamicProxy is one good way to do this. Castle DynamicProxy是执行此操作的一种好方法。


EDIT: 编辑:

Actually, I'm not sure if Castle supports adding new properties to the proxy object. 实际上,我不确定Castle是否支持将新属性添加到代理对象。 You might be stuck using IL Emit directly via TypeBuilder . 您可能会直接通过TypeBuilder使用IL Emit陷入困境。 This is non-trivial, as you'll need to learn enough about IL Emit to generate the property accessors and there's a bit of a learning curve. 这是不平凡的,因为您需要充分了解IL Emit才能生成属性访问器,并且还有一些学习曲线。 That said, it's interesting and fun stuff and worth the effort if you have the time. 就是说,这是有趣而有趣的东西,如果有时间,值得付出努力。

I guess it's about regular GUI element like Grid or PropertyGrid. 我猜这是关于常规GUI元素的,例如Grid或PropertyGrid。

Then I would start from reflecting grid's method that accept class instance as parameter, and if it is possible fill internal Dictionary or Dictionary with my own vales. 然后,我将从反映网格的接受类实例作为参数的方法开始,如果可能的话,用我自己的值填充内部Dictionary或Dictionary。

If this is impossible, instead of Emit, try to use System.CodeDom: http://blogs.msdn.com/b/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx 如果这是不可能的,请尝试使用System.CodeDom代替Emit: http : //blogs.msdn.com/b/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM