Home > Enterprise >  C# record - Assign Multiple Properties using Reflection On Same Instance
C# record - Assign Multiple Properties using Reflection On Same Instance

Time:12-07

Since record type is immutable, a new instance is created whenever a property is set

My question is: using reflection, is it possible to set values to multiple properties without creating new instance on every assignment (same as with reserved word)?

Thank you!

public class Program
{
    public record Person
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

    public static void Main()
    {
        var p = new Person();
        Console.WriteLine("Hashcode BEFORE property assignment: "   p.GetHashCode());
        var pis = p.GetType().GetProperties( BindingFlags.Instance | BindingFlags.Public);
        
        foreach (var pi in pis)
        {
            pi.SetValue(p, "f"); //this line creates and assign a new instance (record is immutable)
            Console.WriteLine($"Hashcode AFTER \'{pi.Name}\' property assignment: "   p.GetHashCode());
        }
    }
}

CodePudding user response:

//this line creates and assign a new instance (record is immutable)

I would argue that this statement is not true.

var p = new Person();
var p1 = p;

// ... your code

Console.WriteLine(object.ReferenceEquals(p, p1)); // prints True

Fiddle.

The hash code change does not prove that a new instance is created - records have GetHashCode generated which will include the declared fields (check at sharplab.io) so changing a field will lead to the hash code change.

So answering your question:

using reflection, is it possible to set values to multiple properties without creating new instance on every assignment

Yes, it is because no new instance created when you manipulate properties with reflection.

CodePudding user response:

What are you trying to achieve? If you look at the C# reference for records:

You can also create records with mutable properties and fields:

public record Person
{
    public string FirstName { get; set; } = default!;
    public string LastName { get; set; } = default!;
};

Ideally there is no reason to use reflection to set those property

but if you want to create an immutable record you should be doing so using one of the following examples.

public record Person(string FirstName, string LastName);

public record Person
{
    public string FirstName { get; init; } = default!;
    public string LastName { get; init; } = default!;
};

However this doesn't prevent using reflection.

  • Related