// // MakeGenericMethod // public override MethodInfo MakeGenericMethod(Type[] typeArguments) { if (!IsGenericMethodDefinition) { throw new InvalidOperationException(); } if (typeArguments == null) { throw new ArgumentNullException(); } var implicitTypeArgs = reflectedType.GetGenericArguments(); int implicitTypeArgsCount = implicitTypeArgs.Length; var explicitTypeArgsCount = typeArguments.Length; int combinedTypeArgsCount = implicitTypeArgsCount + explicitTypeArgsCount; var combinedTypeArgs = new object[combinedTypeArgsCount]; java.lang.System.arraycopy( /* from */ implicitTypeArgs, 0, /* into */ combinedTypeArgs, 0, /* count */ implicitTypeArgsCount); java.lang.System.arraycopy( /* from */ typeArguments, 0, /* into */ combinedTypeArgs, implicitTypeArgsCount, /* count */ explicitTypeArgsCount); var newMethod = new RuntimeMethodInfo(JavaMethod, -1, reflectedType, originalName, strippedName); newMethod.typeArguments = combinedTypeArgs; newMethod.genericFlags = flgGenericMethod; for (int i = 0; i < combinedTypeArgsCount; i++) { var arg = combinedTypeArgs[i] as RuntimeType; if (arg == null) { throw new ArgumentNullException(); } if (arg.IsGenericParameter || arg.ContainsGenericParameters) { newMethod.genericFlags |= flgContainsGenericParameters; } } return(newMethod); }
// // constructor // #pragma warning disable 0436 private RuntimeMethodInfo(java.lang.reflect.Method javaMethod, int modifiers, system.RuntimeType reflectedType, string originalName, string strippedName) #pragma warning restore 0436 { this.JavaMethod = javaMethod; this.reflectedType = reflectedType; this.originalName = originalName; this.strippedName = strippedName; if (modifiers == -1) // if called from MakeGenericMethod { return; } // analyze the method and the declaring type in order to decide what // type of a generic method this is. the general idea is: // if the method takes more generic parameters, than the number of // arguments in the type, then it is a generic method definition. int originalNameLen = originalName.Length; char lastChar = (originalNameLen > 0) ? originalName[originalNameLen - 1] : (char)0; // the actual suffix character is configured in CilMain.cs if (lastChar == '\u00A1' || lastChar == '!') // U+00A1 Inverted Exclamation Mark { if ((modifiers & java.lang.reflect.Modifier.STATIC) == 0) { // if an instance method takes any type arguments at all, // then it must be a generic method definition genericFlags |= flgGenericMethod | flgGenericMethodDefinition | flgContainsGenericParameters; } else { // count the number of type arguments in the declaring type var typeArgsInType = reflectedType.GetGenericArguments(); int numTypeArgsInType = typeArgsInType.Length; // count the number of type parameters in the method signature int numTypeArgsInMethod = 0; var paramTypes = javaMethod.getParameterTypes(); int paramIndex = paramTypes.Length; while (paramIndex-- > 0) { var paramType = paramTypes[paramIndex]; if (paramType != (java.lang.Class) typeof(System.Type)) { break; } numTypeArgsInMethod++; } if (numTypeArgsInMethod == numTypeArgsInType) { // a static method that takes a number of type parameters // equal to the number of arguments in the declaring type. // this means it is not a generic method, but it may not // be invokable, if the declaring type is not concrete. if (reflectedType.ContainsGenericParameters) { genericFlags |= flgContainsGenericParameters; } else if (reflectedType.IsGenericType) { genericFlags |= flgCombineGenericArguments; } } else if (numTypeArgsInMethod > numTypeArgsInType) { // a static method that takes more parameters than the // declaring type, i.e. it is a generic method definition. genericFlags |= flgGenericMethod | flgGenericMethodDefinition | flgContainsGenericParameters; } else { throw new TypeLoadException(originalName); } } } else { // a method that does not take any type argument may still be // not invokable, if the reflected type is not a concrete type. // note that this is true only for instance methods, as static // methods in a generic type will always take type arguments. if ((modifiers & java.lang.reflect.Modifier.STATIC) == 0) { if (reflectedType.ContainsGenericParameters) { genericFlags |= flgContainsGenericParameters; } else if (reflectedType.IsGenericType) { genericFlags |= flgCombineGenericArguments; } } } }