Consider the following test code structure:
class TestClass<T>
{
public object TestObject;
}
class TestClass2<T> :TestClass<T>
{
public int TestMethod()
{}
}
When I add Instruction.Create(OpCodes.Ldfld, TestObjectField)
to TestMethod
, I get the following result:
ldfld class Object TestNamespace.TestClass
`1::TestObject
This causes an issue in the secure plugin system of Dynamics CRM (more information could be found here). However, when I add TestObject = new object()
to TestMethod
, I get the following result, which runs fine:
ldfld class Object class TestNamespace.TestClass
`1<!T>::TestObject
This only happens when the object I am trying to access is in a generic base class. Is there a way that I can simulate the desired result from within Fody please?
UPDATE:
I managed to partially solve the issue by using the following lines:
var testObjectFieldRef = testObjectFieldDefinition?.Resolve().GetGeneric();
var testClassTypeRef = testObjectFieldRef?.DeclaringType.Resolve().GetGeneric();
if (testClassTypeRef != null)
{
testObjectFieldRef.DeclaringType = testClassTypeRef;
}
It seems that by default the ModuleDefinition does not provide a generic type/field definition; so it has to be done explicitly. In addition, the types of the generic parameters are not specified, so it's still an issue.
I managed to solve this issue by using the following code (reference):
var genericBaseType = (GenericInstanceType) testClassTypeRef.BaseType;
var genericArgs = genericBaseType .GenericArguments;
var fullBaseTypedName = genericBaseType.ElementType.MakeGenericInstanceType(genericArgs.ToArray()).FullName
Which returns ldfld class Object class TestNamespace.TestClass
`1<!T>::TestObject
as required. It will also fill in the type of the type parameter (in place of <!T>
) if given in the derived class.