In first thank you so much for so useful reply!

But I have next question:

1) If I have (for ex)

  public static class First
  {
    public static class Second<T>
    {
      public static class Third
      {
        public static int field;
      }
    }
  }

then really I have following:

  public static class First
  {
    public static class Second<T>
    {
      public static class Third<T>   <-- HERE
      {
        public static int _field;
      }
    }
  }

AND when I need to have access to field "_field" do I need to
instanciate by generic only Third class type or I should instanciate
base classes too? May be I should put T generic parameter of Second<T>
as argument of Third?

On 25 май, 14:03, Gábor Kozár <[email protected]> wrote:
> 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