我在发出呼叫给发出时其类型未完成的代理时遇到问题。我会详细说明:我已经声明了以下委托类型:如何在发出时向未完成类型的代理发出呼叫?
// Delegate type. The 'firstArgument' will be 'this', i.e., this is an open
// instance method: the implicit argument is here given explicitly, in
// 'firstArgument'. (See link below for explanation on open instance delegates).
public delegate Object DirectReadAccessor<T>(T firstArgument);
现在我想要动态(即用TypeBuilder)创建下面的类:
public MyClass {
// Array of delegates. T has been replaced with MyClass because the
// argument will be 'this', which is of type MyClass.
private static DirectReadAccessor<MyClass>[] directReadAccessors;
// Method that looks up a delegate in the array of delegates and calls it
// with 'this'.
public Object DirectRead(int i) {
directReadAccessors[i](this);
}
// Method that is called by the declaring type to pass an array with the
// MethodInfo of some methods. MyClass then creates delegates for these
// methods and stores them in the directReadAccessors array.
public static void InitializeClass(MethodInfo[] directReadAccessorsMInfo) {
int length = directReadAccessorsMInfo.Length;
Type[] typeArguments = new Type[] { typeof(MyClass) };
directReadAccessors = new DirectReadAccessor<MyClass>[length];
// For each method in directReadAccessorsMInfo...
for (int i = 0; i < length; i++) {
// Create a delegate and store it in directReadAccessors.
directReadAccessors[i] = (DirectReadAccessor<MyClass>)
Delegate.CreateDelegate(
DirectReadAccessor<MyClass>, // Type of the delegate.
null, // Specify null first argument so that it's
// *open* instance.
directReadAccessorsMInfo[i].MakeGenericMethod(typeArguments) // The method.
);
}
}
}
这一直很棘手,因为当我试图声明字段directReadAccessors,它是DirectReadAccessor []类型,或者当我发出方法InitalizeClass,它再次使用MyClass时,MyClass不存在存在(这就是我创建的)。不过,我设法做到了这一切,但现在我在DirectRead方法中遇到了问题,因为我不知道如何在堆栈中调用委托时调用该委托。显然,我需要的是下面的Emit:
ilGenerator.Emit(OpCodes.Callvirt, invokeMInfo);
其中invokeMInfo是DirectReadAccessor的方法调用,而我应该得到像这样:
MethodInfo invokeMInfo = typeof(DirectReadAccessor<MyClass>).GetMethod(
"Invoke", // Name of the method.
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, // Binding attributes.
null, // Binder.
new Type[] { typeof(MyClass) }, // Types of the arguments.
null // Modifiers for the arguments.
);
再次,问题是,无论是MyClass的,也不DirectReadAccessor存在。我有一个MyClass的和未完成的DirectReadAccessor类型TypeBuilder,我已经是这样创建的:
directReadAccessorType = typeof(DirectReadAccessor<>).MakeGenericType(typeBuilder);
但是,如果我尝试调用GetMethod(“调用”,....)上directReadAccessorType如上图所示,我得到一个NotSupportedException,因为我无法获取未完成类型的方法Invoke。我已经最后定稿类型后进行相同的呼叫测试这个假设:
typeBuilder.CreateType();
事实上我不明白在这种情况下例外。不过,我需要能够在最终确定类型之前获取Invoke方法的MethodInfo,同时发出InitializeClass的代码。
这是一个奇怪的情况:当我需要它时,我将拥有委托,但是我无法生成代码来调用它。任何人都可以提供帮助吗?
非常感谢,对于冗长的帖子感到抱歉。
没有进攻的线路的呼叫,但它只是我,还是开发者编写的代码是太复杂了? ? – 2010-03-03 08:31:49
没有采取。这是一个为期5个月的项目,尝试将C#移植到一个非常复杂的预先存在的系统中。 事实上,我在这里试图做的并不是那么复杂,我只是有一个委托阵列,并希望能够调用它们,就这些。唯一的问题是我正在使用一个动态创建的类型,但是如果你不允许使用这种类型,那么首先提供这个功能有什么意义? – Alix 2010-03-03 10:07:53