Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# &引用;未能解析T[]modreq(System.Runtime.CompilerServices.IsVolatile)";_C#_Cil_Mono.cecil - Fatal编程技术网

C# &引用;未能解析T[]modreq(System.Runtime.CompilerServices.IsVolatile)";

C# &引用;未能解析T[]modreq(System.Runtime.CompilerServices.IsVolatile)";,c#,cil,mono.cecil,C#,Cil,Mono.cecil,用户报告了以下错误消息: 无法解析T[]modreq(System.Runtime.CompilerServices.IsVolatile) 这是有问题的代码行: public static TypeDefinition ResolveTypeReference(this TypeReference typeReference) { return typeReference.Resolve() ?? throw new ResolutionException(typeReference)

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

无法解析T[]modreq(System.Runtime.CompilerServices.IsVolatile)

这是有问题的代码行:

public static TypeDefinition ResolveTypeReference(this TypeReference typeReference)
{
    return typeReference.Resolve() ?? throw new ResolutionException(typeReference);
}
此方法在操作码为
操作码.Ldfld
操作码.Ldobj
的指令的操作数上调用

ResolutionException
MonoCecil
库中的一个类:

public ResolutionException(MemberReference member)
  : base("Failed to resolve " + member.FullName)
{
  if (member == null)
    throw new ArgumentNullException(nameof (member));
  this.member = member;
}
也就是说,有问题的
TypeReference
FullName
属性的值是
T[]modreq(System.Runtime.CompilerServices.IsVolatile)

不幸的是,我没有更多的堆栈跟踪可供共享,因此请原谅我的模糊问题:

  • 在什么情况下,
    TypeReference
    FullName
    属性设置为
    T[]modreq(System.Runtime.CompilerServices.IsVolatile)
  • 它的不可解决性是由于它具有特定的
    全名的相同原因,还是由于其他原因
  • 您能否提供一些示例C#代码,将其反编译成具有该全名的东西?当我反编译以下代码时
  • 公共C类
    {
    公共挥发性T[]字段;
    公屋
    {
    var-temp=字段;
    }
    }
    
    兴趣的指导是

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

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

    我最终解决了这个问题,检查我正在解析的类型是否是RequiredModifierType,然后再解析它的元素类型(如果是该类型)

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

    没有太多(任何?)文档,但Cecil似乎将volatile修饰符作为一种封闭类型进行了表面处理。据我所知,解决这个问题总是失败的。

    看起来像是Cecil的一个缺陷/限制。
    modreq
    表示
    字段
    volatile
    ,需要将其传递给方法,以确保JIT只生成
    volatile.
    前缀访问。这是正确的,Cecil认为它是类型名称的一部分是不正确的(但如果您生成访问操作码,那么它是类型的一部分可以被认为是“正确的”,所以是的)。准确地说,
    字段的类型实际上是
    T[]modreq(IsVolatile)
    ,由于
    modreq
    修饰符是该类型的一部分,但是尝试将其用作完整的类型名是不正确的/将失败,因为它是基于
    T[]
    的类型,其中
    T
    是该类的第一个泛型参数(这就是
    !0
    的意思;在IL级别上,类型参数除了用于漂亮打印之外没有其他名称)。在“正常”反射中,这不是通过
    类型
    而是通过
    字段信息。GetRequiredCustomModifiers()公开的
    @jeroenmoster感谢您的回复。出于好奇,我试图用一个包含
    public volatile int[]的类来重现这个错误字段
    ,但我无法。键入解析成功,并且未引发任何
    ResolutionException
    。根据您的解释,我本以为会遇到相同的错误。我是否误解了什么?不,这只是表明,显然是错误(如果它是一个bug,可能只是一个API限制或误用,我无法真正判断,因为我对Cecil几乎没有经验)被限制为泛型类型(甚至可能是泛型类型的数组)。解析逻辑显然不会在
    modreq(Volatile)上出错
    一般来说。您应该看看
    ResolveTypeReference
    是如何被调用的——我可以很容易地想象,试图将一个开放泛型类型(
    C
    )字段的“类型”解析为这种方式失败。
    if (tr is RequiredModifierType)
        tr = tr.GetElementType();
    var td = tr.Resolve();