Выпуск доступа к полям в базовом классе, используя Fody
Рассмотрим следующую структуру кода теста:
class TestClass<T>
{
public object TestObject;
}
class TestClass2<T> :TestClass<T>
{
public int TestMethod()
{}
}
Когда я добавлю Instruction.Create(OpCodes.Ldfld, TestObjectField)
в TestMethod
, Я получаю следующий результат:
ldfld class Object TestNamespace.TestClass
`1::TestObject
Это вызывает проблему в системе безопасных плагинов Dynamics CRM (дополнительную информацию можно найти здесь). Тем не менее, когда я добавляю TestObject = new object()
в TestMethod
, Я получаю следующий результат, который работает нормально:
ldfld class Object class TestNamespace.TestClass
`1<!T>::TestObject
Это происходит только тогда, когда объект, к которому я пытаюсь получить доступ, находится в базовом базовом классе. Есть ли способ, которым я могу симулировать желаемый результат из Fody, пожалуйста?
ОБНОВИТЬ:
Мне удалось частично решить проблему, используя следующие строки:
var testObjectFieldRef = testObjectFieldDefinition?.Resolve().GetGeneric();
var testClassTypeRef = testObjectFieldRef?.DeclaringType.Resolve().GetGeneric();
if (testClassTypeRef != null)
{
testObjectFieldRef.DeclaringType = testClassTypeRef;
}
Кажется, что по умолчанию ModuleDefinition не предоставляет определения общего типа / поля; так что это должно быть сделано явно. Кроме того, типы общих параметров не указаны, поэтому это все еще проблема.
1 ответ
Мне удалось решить эту проблему с помощью следующего кода ( ссылка):
var genericBaseType = (GenericInstanceType) testClassTypeRef.BaseType;
var genericArgs = genericBaseType .GenericArguments;
var fullBaseTypedName = genericBaseType.ElementType.MakeGenericInstanceType(genericArgs.ToArray()).FullName
Который возвращается ldfld class Object class TestNamespace.TestClass
`1<!T>::TestObject
как требуется. Это также заполнит тип параметра типа (вместо <!T>
) если дано в производном классе.