使用 Fody 在通用基础 class 中发布访问字段
Issue accessing fields in generic base class using 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 的安全插件系统出现问题(可以找到更多信息 here)。但是,当我将 TestObject = new object()
添加到 TestMethod
时,我得到了以下运行良好的结果:
ldfld class Object class TestNamespace.TestClass
`1<!T>::TestObject
只有当我试图访问的对象位于通用基础 class 中时才会发生这种情况。有什么方法可以让我在 Fody 中模拟出想要的结果吗?
更新:
我使用以下几行设法部分解决了问题:
var testObjectFieldRef = testObjectFieldDefinition?.Resolve().GetGeneric();
var testClassTypeRef = testObjectFieldRef?.DeclaringType.Resolve().GetGeneric();
if (testClassTypeRef != null)
{
testObjectFieldRef.DeclaringType = testClassTypeRef;
}
似乎默认情况下 ModuleDefinition 不提供通用的 type/field 定义;所以它必须明确地完成。另外,泛型参数的类型没有规定,所以还是个问题。
我设法使用以下代码 (reference) 解决了这个问题:
var genericBaseType = (GenericInstanceType) testClassTypeRef.BaseType;
var genericArgs = genericBaseType .GenericArguments;
var fullBaseTypedName = genericBaseType.ElementType.MakeGenericInstanceType(genericArgs.ToArray()).FullName
其中 returns ldfld class Object class TestNamespace.TestClass
`1<!T>::TestObject
根据需要。如果在派生的 class.
中给出,它还将填写类型参数的类型(代替 <!T>
)
考虑以下测试代码结构:
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 的安全插件系统出现问题(可以找到更多信息 here)。但是,当我将 TestObject = new object()
添加到 TestMethod
时,我得到了以下运行良好的结果:
ldfld class Object class TestNamespace.TestClass
`1<!T>::TestObject
只有当我试图访问的对象位于通用基础 class 中时才会发生这种情况。有什么方法可以让我在 Fody 中模拟出想要的结果吗?
更新:
我使用以下几行设法部分解决了问题:
var testObjectFieldRef = testObjectFieldDefinition?.Resolve().GetGeneric();
var testClassTypeRef = testObjectFieldRef?.DeclaringType.Resolve().GetGeneric();
if (testClassTypeRef != null)
{
testObjectFieldRef.DeclaringType = testClassTypeRef;
}
似乎默认情况下 ModuleDefinition 不提供通用的 type/field 定义;所以它必须明确地完成。另外,泛型参数的类型没有规定,所以还是个问题。
我设法使用以下代码 (reference) 解决了这个问题:
var genericBaseType = (GenericInstanceType) testClassTypeRef.BaseType;
var genericArgs = genericBaseType .GenericArguments;
var fullBaseTypedName = genericBaseType.ElementType.MakeGenericInstanceType(genericArgs.ToArray()).FullName
其中 returns ldfld class Object class TestNamespace.TestClass
`1<!T>::TestObject
根据需要。如果在派生的 class.
<!T>
)