Python.Runtime.DelegateManager.GetDispatcher C# (CSharp) Метод

GetDispatcher() приватный статический Метод

private static GetDispatcher ( Type dtype ) : Type
dtype System.Type
Результат System.Type
	private static Type GetDispatcher(Type dtype) {

	    // If a dispatcher type for the given delegate type has already 
	    // been generated, get it from the cache. The cache maps delegate
	    // types to generated dispatcher types. A possible optimization
	    // for the future would be to generate dispatcher types based on
	    // unique signatures rather than delegate types, since multiple
	    // delegate types with the same sig could use the same dispatcher.

	    Object item = cache[dtype];
	    if (item != null) {
		return (Type)item;
	    }

	    string name = "__" + dtype.FullName + "Dispatcher";
	    name = name.Replace('.', '_');
	    name = name.Replace('+', '_');
	    TypeBuilder tb = CodeGenerator.DefineType(name, basetype);

	    // Generate a constructor for the generated type that calls the
	    // appropriate constructor of the Dispatcher base type.

	    MethodAttributes ma = MethodAttributes.Public |
		                  MethodAttributes.HideBySig |
		                  MethodAttributes.SpecialName | 
		                  MethodAttributes.RTSpecialName;
	    CallingConventions cc = CallingConventions.Standard;
	    Type[] args = {ptrtype, typetype};
	    ConstructorBuilder cb = tb.DefineConstructor(ma, cc, args);
	    ConstructorInfo ci = basetype.GetConstructor(args);
	    ILGenerator il = cb.GetILGenerator();
	    il.Emit(OpCodes.Ldarg_0);
	    il.Emit(OpCodes.Ldarg_1);
	    il.Emit(OpCodes.Ldarg_2);
	    il.Emit(OpCodes.Call, ci);
	    il.Emit(OpCodes.Ret);

	    // Method generation: we generate a method named "Invoke" on the
	    // dispatcher type, whose signature matches the delegate type for
	    // which it is generated. The method body simply packages the
	    // arguments and hands them to the Dispatch() method, which deals
	    // with converting the arguments, calling the Python method and
	    // converting the result of the call.

	    MethodInfo method = dtype.GetMethod("Invoke");
	    ParameterInfo[] pi = method.GetParameters();

	    Type[] signature = new Type[pi.Length];
	    for (int i = 0; i < pi.Length; i++) {
		signature[i] = pi[i].ParameterType;
	    }

	    MethodBuilder mb = tb.DefineMethod(
				  "Invoke",
				  MethodAttributes.Public, 
				  method.ReturnType,
				  signature
				  );

	    ConstructorInfo ctor = listtype.GetConstructor(Type.EmptyTypes);
	    MethodInfo dispatch = basetype.GetMethod("Dispatch");
	    MethodInfo add = listtype.GetMethod("Add");

	    il = mb.GetILGenerator();
	    il.DeclareLocal(listtype);
	    il.Emit(OpCodes.Newobj, ctor);
	    il.Emit(OpCodes.Stloc_0);

	    for (int c = 0; c < signature.Length; c++) {
		Type t = signature[c];
		il.Emit(OpCodes.Ldloc_0);
		il.Emit(OpCodes.Ldarg_S, (byte)(c + 1));

		if (t.IsValueType) {
		    il.Emit(OpCodes.Box, t);
		}

		il.Emit(OpCodes.Callvirt, add);
		il.Emit(OpCodes.Pop);
	    }

	    il.Emit(OpCodes.Ldarg_0);
	    il.Emit(OpCodes.Ldloc_0);
	    il.Emit(OpCodes.Call, dispatch);

	    if (method.ReturnType == voidtype) {
		il.Emit(OpCodes.Pop);
	    }

	    il.Emit(OpCodes.Ret);

	    Type disp = tb.CreateType();
	    cache[dtype] = disp;
	    return disp;
	}