Well, this doesn't seem to be working. I attached my code (it's a little bit
long and the indentation is lost if I copy it in here) - I'm getting an
InvalidCastException: Unable to cast object of type
'Mono.Cecil.GenericInstanceMethod' to type 'Mono.Cecil.IMemberDefinition'.
I need an IMemberDefinition, but there seem to be no way of having one. What
am I doing wrong?
Thank you!
2010/7/3 Jb Evain <[email protected]>
> Hey,
>
> On Sat, Jul 3, 2010 at 8:39 PM, Gábor Kozár <[email protected]> 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 <[email protected]>
>
> --
> --
> mono-cecil
--
--
mono-cecilpublic static IMemberDefinition ResolvePreserve(this MemberReference memberRef)
{
var genericInst = memberRef as IGenericInstance;
if (genericInst != null)
{
// generic instance
IGenericInstance resolvedGenType = null;
if(memberRef is TypeReference)
{
var currentGenType = (GenericInstanceType) memberRef;
resolvedGenType = new
GenericInstanceType((TypeReference)currentGenType.ElementType.ResolvePreserve());
}
else if(memberRef is MethodReference)
{
var currentGenMethod = (GenericInstanceMethod) memberRef;
resolvedGenType = new GenericInstanceMethod((MethodReference)
currentGenMethod.ElementMethod.ResolvePreserve());
}
else
{
throw new ArgumentException("Unrecognised generic member reference
type: " + memberRef.FullName);
}
foreach (TypeReference genArg in genericInst.GenericArguments)
{
resolvedGenType.GenericArguments.Add(genArg);
}
return (IMemberDefinition)resolvedGenType; // InvalidCastException here
}
// do the resolving
var asTypeRef = memberRef as TypeReference;
var asMethodRef = memberRef as MethodReference;
var asFieldRef = memberRef as FieldReference;
IMemberDefinition result = null;
if(asTypeRef != null)
{
result = asTypeRef.Resolve();
}
else if(asMethodRef != null)
{
result = asMethodRef.Resolve();
}
else if(asFieldRef != null)
{
result = asFieldRef.Resolve();
}
else
{
throw new ArgumentException("Unrecognised member reference type: " +
memberRef.ToString(), "memberRef");
}
return result;
}