使用Mono.Cecil将索引器添加到TypeDefinition

时间:2011-08-25 18:18:30

标签: c# mono.cecil

我正在使用JB Evain的Mono.Cecil对已编译的DLL执行一些字节码操作。该项目的一部分是将属性注入TypeDefinitions,使用PropertyDefinitions有效地将编译的getter / setter转换为C#Properties模式。这部分运作良好。

但是,我想在TypeDefinition中添加一个索引器,但是我找不到任何关于如何最好地实现此目的的文档或建议。将用于处理索引请求的方法已经到位:

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

我需要做的就是添加元数据以将它们转换为索引器....

任何想法/想法都会有很大的意义!

1 个答案:

答案 0 :(得分:5)

元数据明智的索引器是简单的属性。只有该类型使用特殊属性进行修饰,以告知该属性是索引器。这是一个示例实现,它添加了一个被识别为索引器的新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);

当然,您也可以创建一个指向现有方法的属性,只要您具有适当的属性即可。