【发布时间】:2020-03-31 03:47:05
【问题描述】:
我正在尝试使用 Fody 编织一个方法调用来解决导致 ReactiveUI 和 PropertyChanged.Fody 之间不兼容的问题
现在这个实现对我所有的测试用例都很好,除了一个 - 将它编织成一个开放的泛型类型。
以下是重要的部分:
- 创建方法引用
//get the method to call
var reactiveExRaiseMethod = FindTypeDefinition("ReactiveUI.IReactiveObjectExtensions").GetMethods().Single(x => x.Name == "RaisePropertyChanged");
var reactiveExRaiseMethodRef = ModuleDefinition.ImportReference(reactiveExRaiseMethod);
var raiseMethod = reactiveExRaiseMethodRef.MakeGenericMethod(type);
- 生成 IL
var il = method.Body.GetILProcessor();
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Call, raiseMethod);
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Ret);
-
MakeGenericMethod(不确定这是否正确 - 在另一篇文章中找到)
public static MethodReference MakeGenericMethod(this MethodReference self, params TypeReference[] arguments)
{
if (self.GenericParameters.Count != arguments.Length)
throw new ArgumentException();
var instance = new GenericInstanceMethod(self);
foreach (var argument in arguments)
instance.GenericArguments.Add(argument);
return instance;
}
- 调用此代码
public class ReactiveObjectPropertyChangeFix : BaseModuleWeaver
{
public override void Execute()
{
foreach (var type in ModuleDefinition.Types)
{
VisitType(type); //this subsequently passes this reference to the code shown above
}
运行它对除了开放的泛型类型之外的所有东西都很好
当我在 ILSpy 中查看生成的代码时,我发现它生成了这个:
public class MyReactiveObject<T> : ReactiveObject
{
protected void OnPropertyChanged(string propertyName)
{
((MyReactiveObject<>)this).RaisePropertyChanged(propertyName);
}
}
而不是这个(取自通过的测试用例对象):
public class MyReactiveObject : ReactiveObject
{
protected void OnPropertyChanged(string propertyName)
{
this.RaisePropertyChanged(propertyName);
}
}
我知道MakeGenericReference() 创建的引用有问题,但我无法弄清楚它是什么,在封闭的通用实例(例如MyReactiveObject<string>)上运行代码时的错误是:
System.TypeLoadException:无法从程序集“Weavers.Tests,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”加载类型“Weavers.Tests.MyReactiveObject`1”。
【问题讨论】:
标签: c# mono.cecil fody