I've run across some odd behavior in Mono.Cecil. Enumerating the
instructions of two methods with similar signatures in two different
types that use GenericParameters causes Mono.Cecil to return the
GenericParameter for the first method only. Is it possible that
GenericParameters are cached in some way across multiple types? I will
try and step thru the Mono.Cecil code and see if I can narrow down
this issue. For now here's the test case I have that shows the
symptom:
using System;
using System.Linq;
using System.Diagnostics;
using System.Reflection;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace CecilBug1
{
class GenericTypeTest<T>
{
public bool AreEqual<U>(U expected, U actual) {
var equal = expected.Equals(actual);
Console.WriteLine(equal);
return equal;
}
}
class GenericMethodTest
{
public bool AreEqual<T>(T expected, T actual) {
var equal = expected.Equals(actual);
Console.WriteLine(equal);
return equal;
}
}
class Program
{
static void Main(string[] args) {
var reflectionAssembly =
Assembly.GetExecutingAssembly();
var asm =
AssemblyFactory.GetAssembly(reflectionAssembly.Location);
var genericTypeTest =
asm.MainModule.Types["CecilBug1.GenericTypeTest`1"];
var genericMethodTest =
asm.MainModule.Types["CecilBug1.GenericMethodTest"];
// void GenericTypeTest<T>::AreEqual<U>(U expected, U
actual)
var method1 =
genericTypeTest.Methods.GetMethod("AreEqual").First();
ProcessMethod(method1, "U");
// void GenericMethodTest::AreEqual<T>(T expected, T
actual)
var method2 =
genericMethodTest.Methods.GetMethod("AreEqual").First();
ProcessMethod(method2, "T");
}
static void ProcessMethod(MethodDefinition method, string
expectedName) {
Console.WriteLine(method);
var body = method.Body;
foreach (Instruction cil in body.Instructions) {
var genericParameter = cil.Operand as
GenericParameter;
if (genericParameter != null) {
Debug.Assert(expectedName ==
genericParameter.FullName);
Console.WriteLine(genericParameter);
}
}
}
}
}
--
--
mono-cecil