Consider the following situation: You retrieve a method reference from
the .Overrides list which refers to a method in another assembly; then
you .Resolve() that method reference to get the method definition from
the other assembly; and then you use .Import() to import it back into
the same module it was originally in.
I realise that .Import() is probably free to create new instances of
any references — it is not *required* to return the same instance for
the same thing. However, it would be nice if it did.
In the following code, I demonstrate this situation: the code
currently outputs “False” because the two GenericParameter instances
do not compare equal, but it would be nice if it returned “True”, i.e.
if .Import() made sure to return the same GenericParameter instance
that is already present in the method .override declaration:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Mono.Cecil;
namespace Timwi.Temp {
class MyClass<T> : ICollection<T>
{
// Use Visual Studio to fill this class with
// *explicit* interface implementations
// for ICollection<T>
}
static class Program
{
static void Main()
{
var assembly = AssemblyDefinition.ReadAssembly(
Assembly.GetExecutingAssembly().Location);
foreach (var type in assembly.MainModule.Types
.Where(t => t.FullName == "Timwi.Temp.MyClass`1"))
{
var name = "System.Collections.Generic." +
"ICollection<T>.CopyTo";
foreach (var meth in type.Methods
.Where(m => m.Name == name)
.SelectMany(m => m.Overrides))
{
var arr = (ArrayType)meth.Parameters[0].ParameterType;
var genParam1 = (GenericParameter)arr.ElementType;
// Notice that this outputs "!0"
Console.WriteLine(genParam1.FullName);
var resolved = meth.Resolve();
var imp = assembly.MainModule.Import(resolved);
var arr2 = (ArrayType)imp.Parameters[0].ParameterType;
var genParam2 = (GenericParameter)arr2.ElementType;
// Notice that this outputs "T"
Console.WriteLine(genParam2.FullName);
// This line unfortunately outputs False
Console.WriteLine(genParam1 == genParam2);
}
}
Console.ReadLine();
}
}
}
--
--
mono-cecil