"Не удалось разрешить T [] modreq (System.Runtime.CompilerServices.IsVolatile)" - PullRequest
1 голос
/ 21 января 2020

Пользователь сообщил следующее сообщение об ошибке:

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

Это неправильная строка кода:

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

Этот метод вызывается из операндов инструкций с кодами операций OpCodes.Ldfld или OpCodes.Ldobj.

ResolutionException является классом в библиотеке MonoCecil:

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

Т.е. значение свойства FullName нарушающего TypeReference равно T[] modreq(System.Runtime.CompilerServices.IsVolatile).

К сожалению, у меня нет больше трассировки стека, поэтому извините за смутные вопросы:

  1. В каком сценарии ios свойство FullName TypeReference имеет значение T[] modreq(System.Runtime.CompilerServices.IsVolatile)?
  2. Является ли его неразрешимость по той же причине, по которой он имеет этот конкретный Fullname, или это из-за какой-то другой причины?
  3. Можете ли вы предоставить пример кода C#, который декомпилируется в нечто, имеющее точно это полное имя? Когда я декомпилирую следующий код внутри 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[] используется для представления универсальный массив c, а не T[]. Это мотивирует мой первый вопрос.

1 Ответ

1 голос
/ 24 января 2020

В итоге я обошел эту проблему, проверив, является ли тип, который я разрешал, типом RequiredModifierType, прежде чем выполнять разрешение и определение типа его элемента, если он относится к этому типу.

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

Нет не так много (любой?) документации, но кажется, что Сесил рассматривает модификатор volatile как закрывающий тип. Насколько я могу судить, решение этой проблемы всегда будет неудачным.

...