Here is a minimalist example to show what I've run into:
-----------------------------------------------------------------------
class Test<U> : IEnumerable<U>
{
// This is an implicit implementation, so it doesn’t have an
// override declaration
public IEnumerator<U> GetEnumerator() { return null; }
// (don’t care about this one)
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{ return null; }
}
partial class Program
{
static void Main(string[] args)
{
var self = AssemblyDefinition.ReadAssembly(
Assembly.GetExecutingAssembly().Location);
var TestU = self.MainModule.Types.Single(
t => t.FullName == "X.Test`1");
// This gets me the method declared above, to which I want to
// add an explicit override declaration
var TestUGetEnumerator = TestU.Methods.Single(
t => t.Name == "GetEnumerator");
var IEnumerableU = TestU.Interfaces.Single(i => i.FullName
.StartsWith("System.Collections.Generic.IEnumerable`1"));
var IEnumerable = IEnumerableU.GetElementType().Resolve();
// This gets me the right method in the original,
// non-constructed generic IEnumerable<T> type
var IEnumerableGetEnumerator = IEnumerable.Methods.Single(
m => m.Name == "GetEnumerator");
// Try to add the override!
TestUGetEnumerator.Overrides.Add(IEnumerableGetEnumerator);
self.Write("Temp_out.exe");
}
}
-----------------------------------------------------------------------
Of course, this doesn't work because IEnumerableGetEnumerator contains
the method from the unconstructed type, but we need one for the
constructed type IEnumerable<U>, which I have in IEnumerableU. So I
tried to create a MethodReference for this:
-----------------------------------------------------------------------
var newMethodReference = new MethodReference("GetEnumerator",
IEnumerableGetEnumerator.ReturnType)
{
DeclaringType = IEnumerableU,
HasThis = IEnumerableGetEnumerator.HasThis,
ExplicitThis = IEnumerableGetEnumerator.ExplicitThis,
CallingConvention = MethodCallingConvention.Generic
};
// This method doesn't have any parameters, but if it did,
// I would add them like this
foreach (var parameter in IEnumerableGetEnumerator.Parameters)
newMethodReference.Parameters.Add(new ParameterDefinition(
parameter.ParameterType));
// Try to add the override!
TestUGetEnumerator.Overrides.Add(newMethodReference);
self.Write("Temp_out.exe");
-----------------------------------------------------------------------
Unfortunately, this still doesn't work. PEVerify shows the following
validation error:
[MD]: Error: Signature has an invalid token (token: 0x02000036;
offset: 0x00000004). [token:0x0A000069]
[MD]: Error: Signature has generic type of arity 0 instantiated at
different arity 1 at byte=0x00000007. [token:0x0A000069]
What am I doing wrong?
Many thanks!
Timwi
--
--
mono-cecil