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-cecil
public 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;
}

Reply via email to