[Mono-dev] Mono.Cecil: Full names of generic types

Matej Urbas matej.urbas at gmail.com
Mon Jul 24 06:11:12 EDT 2006


On Mon, 2006-07-24 at 11:20 +0200, Jb Evain wrote:
> You can find constructed generic types (GenericInstanceType) and 
> constructed generic methods (GenericInstanceMethod).
> 
> They both implement IGenericInstance wich provides a collection of 
> argument. An argument is a TypeReference, which is the base class for 
> any kinf of type (hence, it could be a TypeDefinition as well as another 
> GenericInstanceType).

Thanks! I figured that out yesterday, just before I wanted to start
writing the 'name parser' :D


I have one question though:

Suppose we have such a TypeReference: SomeType`2<int, T>[][]

Here is what I do to get all info about "SomeType`2" out of there:

I have a loop that goes like this:

Check if the TypeReference is of any of these types:

 1. ArrayType
 2. GenericInstanceType
 3. ReferenceType
 4. PointerType
 5. None of the above

if we stumble on either of cases 1-4, we can cast the TypeReference to
either of them and gather whatever additional info they have (e.g.:
ArrayType gives us info about the Rank, GenericInstanceType gives us
info about GenericAttributes, ReferenceType tells us that the type is
passed ByRef and PointerType gives us the level of indirection).

Moreover, each of the above types has a property named 'ElementType'
which is the one I use to gather all info about the type.

Now in the 5th case, we have only the plain type - without the array
modifier or any generic attributes - which is our end point...

Here is what my algorithm would do (looking at SomeType`2<int, T>[][]):

Step 1: current type is an ArrayType - get its rank <-- now visit its
ElementType
Step 2: current type is an ArrayType - get its rank <-- now visit its
ElementType
Step 3: current type is a GenericInstanceType - traverse its
GenericArguments <--- now visit its ElementType
Step 4: current type falls into the 5th case (its neither an ArrayType
or GenericInstanceType or whatever) - it is simply a TypeReference: with
the name "SomeType`2" <--- without any decorations... <--- I store this
name in MonoDevelop

My question is if there are any other possible TypeReference types
(other then the 4 mentioned above)? Did I miss something?

> 
> > You see, the GenericParameters collection of the 'match' parameter is 
> > empty and its full name has the generic parameters already appended 
> > (i.e.: <T>). Now, in monodevelop I have to extract generic parameters of 
> > such parameters but it seems like there is no other way but to parse 
> > them from the 'full name' string... In fact, one can tell that a method 
> > parameter is generic only if one searches for a &gt; or &lt; character 
> > in its name... I would really like to see those parameters specified in 
> > a collection rather than appended to the string. What can I do about it?
> 
> You can check:
> 
> MethodReference ref = ...;
> GenericInstanceMethod gim = ref as GenericInstanceMethod;
> if (gim != null) {
> 	foreach (TypeReference argument in gim.Arguments) {
> 	}
> }

I see. Do you have a case where we would stumble upon a MethodReference?
I mean, if we go through all types in the MainModule of an assembly,
would we find a method reference with actual arguments specified? Do you
have a C# example of such an occurrence?

> 
> > 3. Oh, and to what extent is Mono.Cecil compatible with 
> > System.Reflection? E.g.: are the Mono.Cecil.GenericParamAttributes and 
> > System.Reflection.GenericParameterAttributes cast safe? - I mean, can 
> > they be cast from one-another and still preserve the expected information?
> 
> Check that the values are the same before doing so. In theory, it "may" 
> work.

Will do that.

Thank you very much!


BTW, Cecil rocks! Great work!


Enjoy,
---
Matej




More information about the Mono-devel-list mailing list