Hi Jean-Baptiste,
I've patched the sources on my machine to handle the above scenario
Following the example you set with types, I added a version of
ImportMethod (in Import.cs around line 242)
that takes an extra IGenericContext argument and modified the
ImportType calls to take advantage of it
My patch works for me but I'm not sure I did everything properly.
Nor am I sure about the reason why DeclaringType is set twice on
reference (once right after new and a second time just before
returning)
I've had another problem with generics this time inside
ImportTypeSpecification() (Import.cs:124)
In the following block,
if (IsGenericInstance (type)) {
var element_type = ImportType (type.GetGenericTypeDefinition (),
context);
var instance = new GenericInstanceType (element_type);
var arguments = type.GetGenericArguments ();
for (int i = 0; i < arguments.Length; i++)
instance.GenericArguments.Add (ImportType (arguments [i],
context));
return instance;
}
I believe generic argument types should should in turn be
"instantiated" if they correspond to GenericTypeDefinition
something in this vein:
for (int i = 0; i < arguments.Length; i++)
{
var argument_type = ImportType(arguments[i], context);
if (arguments[i].IsGenericTypeDefinition)
{
var argument_instance = new
GenericInstanceType(argument_type);
var argument_arguments = arguments[i].GetGenericArguments();
for (int j = 0; j < argument_arguments.Length; j++)
argument_instance.GenericArguments.Add(ImportType(argument_arguments[j],
context));
argument_type = argument_instance;
}
instance.GenericArguments.Add(argument_type);
}
in fact, this should be recursive to handle the general case where you
have > 1 level of generic nesting
(i.e. a generic of a generic of a generic ...)
HTH,
Gabriel
On 1 juin, 18:43, Gabriel Kevorkian <[email protected]>
wrote:
> Sure!
> In the Cecil generics issue sample I sent you earlier, paste the
> following:
>
> var assembly =
> AssemblyDefinition.ReadAssembly(@"MyAssembly.dll", new
> ReaderParameters() { ReadSymbols = true });
> var type = assembly.MainModule.Types.FirstOrDefault(t =>
> "A`1".Equals(t.Name));
> var originalPropertyType =
> typeof(MyAssembly.A<>).GetProperty("L").PropertyType;
> // works all right with additional context param
>
> type.Module.Import(typeof(List<>).MakeGenericType(originalPropertyType),
> type);
> // fails with no context param
>
> type.Module.Import(typeof(List<>).MakeGenericType(originalPropertyType).GetConstructor(new
> Type[0]));
>
> The code in "MyAssembly" may be simplified as follows:
>
> namespace MyAssembly
> {
> public class A<T>
> {
> public T L { get { return default(T); } }
> }
>
> }
>
> The second Import statement in the above snippet fails trying to
> import the MethodBase / ConstructorInfo
> (my mistake, I wrote "MethodReference" in my original post)
>
> Cheers,
> Gabriel
>
> On 1 juin, 14:23, Jb Evain <[email protected]> wrote:
>
>
>
> > Hey Gabriel,
>
> > On Tue, Jun 1, 2010 at 12:33 PM, Gabriel Kevorkian
>
> > <[email protected]> wrote:
> > > Sorry for bothering you again but I think it would be great if the
> > > support for specifying a generic context were actually extended to the
> > > overload of ModuleDefinition.Import() taking in a MethodReference as
> > > argument.
>
> > When importing a MethodReference, its DeclaringType becomes the
> > context, so am not exactly sure.
>
> > > using .net reflection on a generic type e.g.
>
> > > public class A<TParam>
> > > {
> > > public TParam L { get { return null; } }
> > > }
>
> > > to:
> > > - retrieve a type defined in terms of a generic parameter,
> > > - use the thus retrieved type to instantiate another generic type, say
> > > List<> ,
> > > - get the constructor so as to be able to perform a new of
> > > List<TParam> within A<TParam>
>
> > Could you post code for those usages, it would be much easier to understand.
>
> > Thanks!
>
> > --
> > Jb Evain <[email protected]>- Masquer le texte des messages précédents -
>
> - Afficher le texte des messages précédents -
--
--
mono-cecil