Okay, that is VERY wrong.

GenericParameters and GenericArguments are two distinct things.
Let me explain it to you with a simple example.

Take this method definition:

public static void Stuff<T>()
{
     ...
}

If you get the MethodDefinition object representing this method declaration,
it'll have a single item in GenericParameters: T. There are NO generic
arguments here, because the method does not known (or care) about what type
will be actually passed to it as T.
However, when you use this method:

Stuff<string>();

Here, in the IL, the 'call' instruction has an operand of type
GenericInstanceMethod (which derives from TypeSpecification, which derives
from TypeReference). It has the same GenericParameters as the definition
above (single item: T), but it also has a GenericArguments property, whose
items represent the types that were actually passed as type parameters to
the method (in this case, as T).
So the GenericArguments collection should have a single item here: a
reference to System.String.

In short: T is the generic parameter, whereas string is the generic
argument. The same goes for types.
Hope it's clear now.

2011/5/25 Stanislav <[email protected]>

> :) My mistake :))
>
>        public static GenericInstanceType MakeGenericSelf(this
> TypeReference typeRef)
>        {
>            var genType = new GenericInstanceType(typeRef);
>            foreach (var p in typeRef.GenericParameters)
>                genType.GenericArguments.Add(p);
>            return genType;
>         }
>
> On 25 май, 13:32, Gábor Kozár <[email protected]> wrote:
> > What is your MakeGenericSelf() extension method? I did not write it, I'm
> > quite positive about it (the linked code only contains various Reference*
> > extension methods, that I did write).
> >
> > Anyway, I see only one problem on this side (although you haven't shown
> the
> > code which emits the IL that actually uses the Utils class you inject
> here):
> >
> > utils = new TypeDefinition(declaringType.FullName, "<>_Utils",
> > TypeAttributes.NestedAssembly | TypeAttributes.Sealed |
> TypeAttributes.Class
> > | TypeAttributes.Abstract, declaringType.Module.GetType<Object>())
> >        {
> >              DeclaringType = resolvedType // here! DeclaringType should
> be
> > set to the original, generic TypeReference, NOT the resolved
> TypeDefinition
> >        };
> >
> > 2011/5/25 Stanislav <[email protected]>
> >
> >
> >
> >
> >
> >
> >
> > > I have a problem making generics. I cannot insert nongeneric class
> > > into generic class as nested. For ex:
> >
> > > Orriginally I have class GenericClass<T>
> >
> > >  public class Something
> > >  {
> > >    public class GenericClass<T>
> > >    {
> > >        public SomeProperty<T> { get; set; }
> > >    }
> > >  }
> > > but when I try to insert new nested class into GenericClass<T>, I
> > > whant to get result:
> >
> > >  public class Something
> > >  {
> > >    public class GenericClass<T>
> > >    {
> > >        private static class Utils
> > >        {
> > >            private static Utils() { /* ... */ }
> > >            public static string field;
> > >        }
> > >        public SomeProperty<T> {
> > >          get { return field; }
> > >          set { /* ... */ }
> > >        }
> > >    }
> > >  }
> >
> > > But in SomeProperty getter I have wrong accessing to GenericClass
> > > field:
> >
> > > Something.GenericClass<>.Utils.field;
> >
> > > generic class GenericClass<> is not instanciated by type.
> >
> > > How do I add nested type (here I use Gabor Kozar's method
> > > MakeGenericSelfhttp://pastebin.com/BTX3AvpV)?
> >
> > > var genericOwnerType = declaringType.HasGenericParameters ?
> > > declaringType.MakeGenericSelf() : null;
> > > var resolvedType = genericOwnerType == null ?
> > > declaringType.Resolve() : genericOwnerType.Resolve();
> >
> > > utils = new TypeDefinition(declaringType.FullName, "<>_Utils",
> > >                           TypeAttributes.NestedAssembly |
> > > TypeAttributes.Sealed | TypeAttributes.Class |
> > >                           TypeAttributes.Abstract,
> > > declaringType.Module.GetType<Object>())
> > >        {
> > >            DeclaringType = resolvedType
> > >        };
> >
> > >        resolvedType.NestedTypes.Add(utils);
> > >        var utilsCctor = new MethodDefinition(".cctor",
> > > MethodAttributes.SpecialName |
> > >                             MethodAttributes.RTSpecialName |
> > > MethodAttributes.HideBySig |
> > >                             MethodAttributes.Static,
> > > declaringType.Module.GetVoidType());
> >
> > > utilsCctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
> > >        utils.Methods.Add(utilsCctor);
> > >        m_utilsClasses.Add(declaringType, utils);
> >
> > > Whats wrong?
> >
> > > On 25 май, 07:23, Stanislav <[email protected]> wrote:
> > > > No, no, all is ok )))) Thank you very much for great help!
> >
> > > > On 24 май, 14:12, Gábor Kozár <[email protected]> wrote:
> >
> > > > > I agree, it's not very intuitive, but that's how it works. You may
> > > write
> > > > > extension methods, or use ones that I've shown in the discussion to
> > > ease the
> > > > > problem.
> > > > > If you can implement it better, please go ahead.
> >
> > > > > 2011/5/24 Stanislav <[email protected]>
> >
> > > > > > > when you Resolve() a TypeReference or MethodReference (or any
> > > > > > > other reference), you loose all generic arguments. You have to
> then
> > > > > > restore
> > > > > > > those generic arguments by essentially cloning the
> MethodReference
> > > (in
> > > > > > your
> > > > > > > case), except setting its DeclaringType to the original
> > > TypeReference
> > > > > > (which
> > > > > > > still contains the generic arguments).
> >
> > > > > > It looks like bug, not as feature )
> >
> > > > > > --
> > > > > > --
> > > > > > mono-cecil
> >
> > > --
> > > --
> > > mono-cecil
>
> --
> --
> mono-cecil

-- 
--
mono-cecil

Reply via email to