On Sat, Jul 3, 2010 at 8:39 PM, Gábor Kozár <kozar...@gmail.com> wrote:
> When I have a MethodReference or TypeReference representing a generic method
> call / object instance, calling Resolve() seems to eliminate the generic
> arguments, resulting in invalid references in the CIL code. Is this
> intentional?
Yes. Resolve returns the corresponding *Definition. There's currently
nothing builtin that does a Resolve + rebuilding of a type spec.
> The problem is that I need to call Resolve(), then manipulate the resulting
> definition object, and I also have to preserve (and manipulate) the generic
> arguments (if any).
> Any hints?
Just implement it on top of Resolve, something like:
public static TypeReference ResolvePreserve (this TypeReference self)
{
if (self.IsGenericInstance) {
var previous_instance = (GenericInstanceType) self;
var instance = new GenericInstanceType
(previous_instance.ElementType.ResolvePreserve ());
foreach (var argument in previous_instance.GenericArguments)
instance.GenericArguments.Add (argument.ResolvePreserve ());
}
if (self.IsArray) {
// ..
}
if (self.IsByReference) {
//
}
return self.Resolve ();
}
--
Jb Evain <j...@nurv.fr>
--
--
mono-cecil
IGenericInstance and IMemberDefinition are completely different
interfaces, you can't cast a IGenericInstance to a IMemberDefinition.
The lowest common denominator here is MemberReference.
You're trying to do to much in one method.
You should have different cases:
TypeReference ResolvePreserved (this TypeReference type)
MethodReference ResolvePreserved (this MethodReference method)
FieldReference ResolvePreserved (this FieldReference field)
The first one needs to deal with type specs like in the code I pasted
here, and the second needs to deal with method specs.
--
Jb Evain <j...@nurv.fr>
Indeed proper design doesn't matter if you want something that can't
possibly exist.
> And a GenericInstanceMethod cannot be cast to TypeDefinition, only
> TypeReference, but I don't need a TypeReference. I need a TypeDefinition.
> What I have seen so far lets me think that it is impossible (by design) for
> a TypeDefinition (or any Definition) to have generic arguments. Or can it be
> solved?
ResolvePreserve can only return a TypeReference because it's the root
of all types. Let's try to make it simple for you.
In your assembly, you have a TypeReference to List<string>.
What you actually have is:
GenericInstanceType
ElementType: TypeReference(List`1)
GenericArguments: TypeReference(String)
Now with ResolvePreserved you want:
GenericInstanceType
ElementType: TypeDefinition(List`1)
GenericArguments: TypeDefinition(String)
And the hierarchy of GenericInstanceType is: TypeReference ->
TypeSpecification -> GenericInstanceType.
So ResolvePreserve needs to return a TypeReference for all
TypeSpecifications, such as arrays. And it's ok, you can write:
TypeReference ResolvePreserved (this TypeReference self);
TypeReference resolved = type.ResolvePreserved ();
if (resolved.IsDefinition) {
TypeDefinition definition = (TypeDefinition) resolved;
// ...
}
--
Jb Evain <j...@nurv.fr>