what is "fieldof()" method in c#

Viewed 513

I decompiled some unity dll files in dnspy and got this line

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

i need to know about the fieldof() function in that line i haven't seen it before (because i'm a beginner)

and two why it shows an error in that line

2 Answers

In MSIL, the intermediate language that C# code (and a bunch of other languages) are compiled into, there is this handy fieldof operator that gets the FieldInfo of fields. However, fieldof doesn't exist in C#.

In C#, you'd need to do something like:

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);

I recommend reading the following starting with C# 8.0 to see what's new in each version of C#.

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

In the earlier days, we were used to implementing properties like the following:

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

So when you decompile an assembly which had a class with this property, you would see the decompiler output exactly like this.

And since C# 2.0, and always with improvements on the way, now there are multiple ways of implementing properties in C#.

public string StringProperty1 => "String Property Value";

public string StringProperty2 { get; private set; }

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

What is common here?

They don't have fields to read from or write into. The fields for this type of declarations are created by the compiler and stored in a structure named PrivateImplementationDetails. This does not have to be a field in its own. It is just the way the runtime accesses the auto-generated private backing fields of your properties.

For instance, for a int[] property with name AProperty, the following IL is generated:

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

And when you look at the constructor IL of this class where you set this property, you see that it is accessing the (backing) field like this:

  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,

And at the end, what you see in your decompiler output means, simply that it is setting the private auto generated field.

Related