"Failed to resolve T[] modreq(System.Runtime.CompilerServices.IsVolatile)"

"Failed to resolve T[] modreq(System.Runtime.CompilerServices.IsVolatile)"

用户报告了以下错误消息:

Failed to resolve T[] modreq(System.Runtime.CompilerServices.IsVolatile)

这是有问题的代码行:

public static TypeDefinition ResolveTypeReference(this TypeReference typeReference)
{
    return typeReference.Resolve() ?? throw new ResolutionException(typeReference);
}

此方法在操作码为 OpCodes.LdfldOpCodes.Ldobj 的指令的操作数上调用。

ResolutionExceptionMonoCecil 库中的 class:

public ResolutionException(MemberReference member)
  : base("Failed to resolve " + member.FullName)
{
  if (member == null)
    throw new ArgumentNullException(nameof (member));
  this.member = member;
}

即违规TypeReferenceFullName属性的值为T[] modreq(System.Runtime.CompilerServices.IsVolatile).

不幸的是,我没有更多的堆栈跟踪可以分享,所以请原谅我的模糊问题:

  1. 什么情况下TypeReferenceFullName 属性设置为T[] modreq(System.Runtime.CompilerServices.IsVolatile)
  2. 它的不可解析性是因为它具有特定的 Fullname 相同的原因,还是由于其他原因?
  3. 您能否提供一些示例 C# 代码,将其反编译为具有 完全 全名的内容?当我反编译下面的代码时 inside SharpLab.io,
public class C<T> 
{
    public volatile T[] field;

    public void M() 
    {
        var temp = field;
    }
}

感兴趣的指令是

IL_0004: ldfld !0[] modreq([System.Private.CoreLib]System.Runtime.CompilerServices.IsVolatile) class C`1<!T>::'field'

!0[]用来表示泛型数组,而不是T[]。这激发了我的第一个问题。

我最终解决了这个问题,方法是在执行解析之前检查我正在解析的类型是否是 RequiredModifierType,如果它是该类型,则解析它的元素类型。

if (tr is RequiredModifierType)
    tr = tr.GetElementType();
var td = tr.Resolve();

没有太多(任何?)文档,但 Cecil 似乎将 volatile 修饰符表面化为封闭类型。据我所知,解决这个问题总是会失败。