使用Mono.将索引器添加到类型定义

本文关键字:类型 定义 添加 Mono 索引 使用 | 更新日期: 2023-09-27 18:06:35

我用JB Evain的Mono。在编译后的DLL上执行一些字节码操作。这个项目的一部分是将属性注入到TypeDefinitions中,使用PropertyDefinitions有效地将编译过的getter/setter转换为c#属性模式。这部分工作正常。

然而,我想添加一个索引器到TypeDefinition,但我找不到任何关于如何最好地实现这一点的文档或建议。用来处理索引请求的方法已经准备好了:

Object getObjectViaIndexer(String str);
void setObjectViaIndexer(String str, object obj);

所有我需要做的是添加元数据转换成索引....

任何想法/想法将非常感谢!

使用Mono.将索引器添加到类型定义

索引器,元数据方面,是简单的属性。只有类型使用特殊属性进行装饰,以表明该属性是索引器。下面是一个示例实现,它添加了一个新的Item属性,该属性被识别为索引器,并委托给现有的方法。

TypeDefinition type = ...;
// public object get_Item (string str) { ... }
var get_item = new MethodDefinition ("get_Item", MethodAttributes.Public, module.TypeSystem.Object);
set_item.Parameters.Add (new ParameterDefinition ("str", ParameterAttributes.None, module.TypeSystem.String));
type.Methods.Add (get_item);
var il = get_item.Body.GetILProcessor ();
il.Emit (...); // emit call to getObjectViaIndexer
// public void set_Item (string str, object obj) { ... }
var set_item = new MethodDefinition ("set_Item", MethodAttributes.Public, module.TypeSystem.Void);
set_item.Parameters.Add (new ParameterDefinition ("str", ParameterAttributes.None, module.TypeSystem.String));
set_item.Parameters.Add (new ParameterDefinition ("obj", ParameterAttributes.None, module.TypeSystem.Object));
type.Methods.Add (set_item);
il = set_item.Body.GetILProcessor ();
il.Emit (...); // emit call to setObjectViaIndexer
// public object this [string str] { ... }
var item = new PropertyDefinition ("Item", PropertyAttributes.None, module.TypeSystem.Object) {
    HasThis = true,
    GetMethod = get_item,
    SetMethod = set_item,
};
type.Properties.Add (item);
// [DefaultMemberAttribute("Item")]
var default_member = new CustomAttribute (module.Import (typeof (System.Reflection.DefaultMemberAttribute).GetConstructor (new [] { typeof (string) })));
default_member.ConstructorArguments.Add (new CustomAttributeArgument(module.TypeSystem.String, "Item"));
type.CustomAttributes.Add (default_member);
当然,你也可以创建一个指向现有方法的属性,只要你有合适的属性。