Home > database >  How does Reflection retrieve data assigned to variables?
How does Reflection retrieve data assigned to variables?

Time:12-31

My understanding so far is that Reflection is used to retrieve the names of Types and their members from an assembly via its metadata. I've come across a few examples of Reflection in action identical to the following example.

class Person
{
    public string Name {get;set;}
}

static void Main(string[] args)
{
    Person person = new Person();
    person.Name = "John";
    Console.WriteLine(person.GetType().GetProperty("Name").GetValue(person)); //John
    person.Name = "Mary";
    Console.WriteLine(person.GetType().GetProperty("Name").GetValue(person)); //Mary
}

I understand how Reflection can get names of Types, members, etc. as this is what's stored in an assembly's metadata, but how does Reflection retrieve the value associated with it? This is dynamic data that changes during a program's execution (as shown in the example), which an assembly's metadata doesn't contain (right?).

Would be grateful for clarification on how Reflection retrieves actual values and whether this is actually the case. Please correct anything I've said that's not correct!

CodePudding user response:

The short answer is that reflection is a feature of the runtime, so it has access to runtime information. Were it a separate library with no runtime "hooks", you're right, it wouldn't be able to get the values of properties at runtime, or make calls, or anything else that wouldn't be essentially observable from the assembly file on disk.

Long answer where I prove this to myself:

Microsoft makes available a reference version of the C# source code used to write the base class libraries for .NET Framework. If we look at the PropertyInfo.GetValue(object) method you use in your example, it's defined enter image description here

Please refer to the part that says Object Instance. An object laid out in memory, contains the following 4 items:

  1. Syncblk
  2. TypeHandle
  3. Instance Fields
  4. String Literals

When you call GetValue, using an OBJECTREF to the object instance, it finds the starting location where your instance fields are stored. From there it can figure out which instance to retrieve based on the type.

I believe the actual call is FieldDesc::GetInstanceField.

  • Related