Updated Analysis: Generic Invoker Types Are Not a Real Problem
Original Concern
The legacy GetInvokerType has a MakeGenericType path for generic C# types. The concern was that the trimmable type map would not handle this.
Investigation Result: All Android invokers are non-generic C# types
Java uses type erasure for generics. The Mono.Android binding generator reflects this — all generated interfaces and their invokers are non-generic C# types, even when the Java type has generic parameters:
// java.util.Iterator<E> → non-generic C# interface + non-generic invoker
[Register("java/util/Iterator", "", "Java.Util.IIteratorInvoker")]
[JavaTypeParameters(new string[] {"E"})] // metadata only, not a C# generic param
public partial interface IIterator : IJavaObject, IJavaPeerable { ... }
[Register("java/util/Iterator", DoNotGenerateAcw=true)]
internal partial class IIteratorInvoker : Java.Lang.Object, IIterator { ... }
The same pattern applies to all 90+ generic Java interfaces:
java/util/List → IList + IListInvoker (non-generic)
java/util/Map → IMap + IMapInvoker (non-generic)
android/os/Parcelable$Creator → IParcelableCreator + IParcelableCreatorInvoker (non-generic)
- etc.
Runtime Flow (Legacy)
- Java returns an object implementing
java.util.Iterator
GetJavaToManagedType("java/util/Iterator") → Java.Util.IIterator (non-generic)
- Since
IIterator is an interface, GetInvokerType(typeof(IIterator)) is called
IIterator has zero generic arguments → takes the simple path: Assembly.GetType("Java.Util.IIteratorInvoker")
IIteratorInvoker is instantiated — no MakeGenericType involved
The MakeGenericType Path Is Dead Code (for Android)
The generic invoker resolution in JavaObjectExtensions.GetInvokerType (lines 137-146) and ManagedTypeManager.GetInvokerTypeCore (lines 48-59) handles C# generics like IFoo<T> → IFooInvoker<T>. But:
- No generated Mono.Android binding produces generic C# invoker types
- No Java.Interop or Java.Base types produce generic C# invoker types
- The code appears to be defensive/future-proofing for a pattern not currently used
Impact on Trimmable Type Map
Low to none. The trimmable path stores InvokerType as a pre-resolved non-generic type reference in the proxy attribute. Since all invokers in Mono.Android are non-generic, this works correctly:
TypeMap entry: "java/util/Iterator" → IIterator_Proxy
IIterator_Proxy.InvokerType → typeof(IIteratorInvoker) // non-generic, resolves fine
Recommendation
This issue can be deprioritized or closed. The generic invoker scenario is theoretical — it would only matter if:
- A third-party binding library creates actual C# generic interfaces (not just
[JavaTypeParameters])
- Someone uses the Java.Interop
[JniTypeSignature] pattern with generic C# types
Neither scenario is common or blocking for .NET 11.
Updated Analysis: Generic Invoker Types Are Not a Real Problem
Original Concern
The legacy
GetInvokerTypehas aMakeGenericTypepath for generic C# types. The concern was that the trimmable type map would not handle this.Investigation Result: All Android invokers are non-generic C# types
Java uses type erasure for generics. The Mono.Android binding generator reflects this — all generated interfaces and their invokers are non-generic C# types, even when the Java type has generic parameters:
The same pattern applies to all 90+ generic Java interfaces:
java/util/List→IList+IListInvoker(non-generic)java/util/Map→IMap+IMapInvoker(non-generic)android/os/Parcelable$Creator→IParcelableCreator+IParcelableCreatorInvoker(non-generic)Runtime Flow (Legacy)
java.util.IteratorGetJavaToManagedType("java/util/Iterator")→Java.Util.IIterator(non-generic)IIteratoris an interface,GetInvokerType(typeof(IIterator))is calledIIteratorhas zero generic arguments → takes the simple path:Assembly.GetType("Java.Util.IIteratorInvoker")IIteratorInvokeris instantiated — noMakeGenericTypeinvolvedThe
MakeGenericTypePath Is Dead Code (for Android)The generic invoker resolution in
JavaObjectExtensions.GetInvokerType(lines 137-146) andManagedTypeManager.GetInvokerTypeCore(lines 48-59) handles C# generics likeIFoo<T>→IFooInvoker<T>. But:Impact on Trimmable Type Map
Low to none. The trimmable path stores
InvokerTypeas a pre-resolved non-generic type reference in the proxy attribute. Since all invokers in Mono.Android are non-generic, this works correctly:Recommendation
This issue can be deprioritized or closed. The generic invoker scenario is theoretical — it would only matter if:
[JavaTypeParameters])[JniTypeSignature]pattern with generic C# typesNeither scenario is common or blocking for .NET 11.