[Mono-list] Obtaining a generic MonoMethod

Raja R Harinath rharinath at novell.com
Tue Dec 5 07:03:45 EST 2006


Hi,

Andreas Färber <andreas.faerber at web.de> writes:

> Am 04.12.2006 um 10:08 schrieb Robert Jordan:
>
>                 I would like to invoke the generic method IList<T>.Add(T) on an
>                 object - how can I do this?
>
>         obtaining a non-zero ICollection`1 MonoClass*, I get a non- 
>         zero mono_class_get_method_from_name(cls, "Add", 1) MonoMethod*  
>         ("System.Collections.Generic.ICollection`1:Add (T)") - but then if I  
>         do mono_object_get_virtual_method, mono_method_full_name on the  
>         returned MonoMethod* says it's System.Object:Finalize()!
>
>         So please consider it a general question: How do I correctly invoke a  
>         generic method? ;-)
>
>     You call methods of generic classes like every other method.
>     The "trick" is to get the method from the "inflated" class,
>     which you can obtain from mono_object_get_class ().
>    
>     MonoClass *clazz = mono_object_get_class (obj);
>
> I'm not so happy with this solution. I thought of this but it's not as simple as that! ;-)
>
> I figured out I always have to use the exact MonoClass the method is declared on.

mono_method_get_class (method)?

> So the above solution will only work if the MonoClass returned by
> mono_object_get_class was in fact the one implementing the correct
> method (as opposed to e.g.: ICollection<T> -> IList <T>:ICollection<T>
> -> OneClass:IList<MyType> -> AnotherClass:OneClass), also this messes
> with overridden/new methods as I wouldn't be using
> mono_object_get_virtual_method that way.

The API only deals with closed generic types/methods.  So the above
inheritance chain would be visible as

  ICollection<MyType> -> IList<MyType> -> OneClass -> AnotherClass

I don't understand the rest of the issues since I'm not familiar with
the embedding API.

> The documentation has some names of functions surrounding generics but they're not really documented:
>
> MonoType*
> mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context);
>
> MonoMethod*
> mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *context);
>
> MonoMethod *
> mono_get_inflated_method (MonoMethod *method);

All these are internal methods, and are meant only to be used by the JIT
compiler (and, even there, it's an unclean API).  Please forget that you
ever heard the word 'inflate' in this context :-)  And ...

> With the parameter being on the interface, do I need to inflate the class or the method or both? Calling mono_get_inflated_method for my
> ICollection`1:Add MonoMethod simply returns my argument!

.. 'mono_get_inflated_method' is essentially obsolete.

> Virtually all other functions have MonoGenericContext arguments - how
> do I obtain such a context? MonoGenericContext is typedef'ed as struct
> _MonoGenericContext and I don't see any helper functions to create it
> or work with its non-declared members.

MonoGenericContext has no user-serviceable parts, and shouldn't have
been exposed, even as just a name, in the first place.  Again, the only
purpose for exposing it is for the JIT.

Currently the only way to work with open generic types is to use
System.Reflection.  I believe it will be that way for some time till we
figure out a reasonable API.

- Hari


More information about the Mono-list mailing list