我在發出呼叫給發出時其類型未完成的代理時遇到問題。我會詳細說明:我已經聲明瞭以下委託類型:如何在發出時向未完成類型的代理髮出呼叫?
// 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