что такое метод fieldof () в c# - PullRequest
5 голосов
/ 04 апреля 2020

Я декомпилировал некоторые файлы Unity DLL в dnspy ​​и получил эту строку

RuntimeHelpers.InitializeArray(array, fieldof(<PrivateImplementationDetails>.51A7A390CD6DE245186881400B18C9D822EFE240).FieldHandle);

Мне нужно знать о функции fieldof () в этой строке, я не видел ее раньше (потому что я новичок)

и два, почему он показывает ошибку в этой строке

Ответы [ 2 ]

7 голосов
/ 04 апреля 2020

В MSIL, промежуточном языке, в который компилируется код C# (и куча других языков), есть этот удобный оператор fieldof, который получает FieldInfo полей. Однако fieldof не существует в C#.

В C# вам нужно сделать что-то вроде:

var type = typeof(EnclosingClass); // "EnclosingClass" is the class this code is in
// assuming PrivateImplementationDetails is private
var fieldInfo = type.GetField("PrivateImplementationDetails", BindingFlags.NonPublic);
RuntimeHelpers.InitializeArray(array, fieldInfo.FieldHandle);
1 голос
/ 04 апреля 2020

Я рекомендую прочитать следующее, начиная с C# 8.0, чтобы увидеть, что нового в каждой версии C#.

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8

В более ранних версиях дни, мы привыкли к реализации таких свойств, как:

private string userName;
public string UserName
{
    get { return userName; }
    set { userName = value; }
}

Поэтому, когда вы декомпилируете сборку, у которой был класс с этим свойством, вы увидите вывод декомпилятора в точности так:

А начиная с C# 2.0, и всегда с улучшениями, теперь есть несколько способов реализации свойств в C#.

public string StringProperty1 => "String Property Value";

public string StringProperty2 { get; private set; }

public ICollection<double> Grades { get; } = new List<double>();

Что здесь общего?

Они нет полей для чтения или записи. Поля для этого типа объявлений создаются компилятором и хранятся в структуре с именем PrivateImplementationDetails. Это не обязательно должно быть поле само по себе. Это просто способ, которым среда выполнения обращается к автоматически сгенерированным частным полям поддержки ваших свойств.

Например, для свойства int [] с именем AProperty генерируется следующий IL:

.field private int32[] '<AProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 

И когда вы смотрите на конструктор IL этого класса, в котором вы устанавливаете это свойство, вы видите, что он обращается к полю (backing) следующим образом:

  IL_0009:  ldc.i4.3
  IL_000a:  newarr     [mscorlib]System.Int32
  IL_000f:  dup
  IL_0010:  ldtoken    field valuetype '<PrivateImplementationDetails>{3CA49917-EFBC-4E01-A884-1CFF6283A97C}'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>{3CA49917-EFBC-4E01-A884-1CFF6283A97C}'::'$$method0x6000029-1'
  IL_0015:  call       void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,

И в конце, что вы Посмотрите в выводе декомпилятора означает, что он просто устанавливает частное автоматически сгенерированное поле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...