繁体   English   中英

C# 记录 - 在同一实例上使用反射分配多个属性

[英]C# record - Assign Multiple Properties using Reflection On Same Instance

由于record类型是不可变的,因此每当设置属性时都会创建一个新实例

我的问题是:使用reflection ,是否可以将值设置为多个属性而无需在每次赋值时创建新实例( with保留字相同)?

谢谢!

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

//此行创建并分配一个新实例(记录是不可变的)

我认为这种说法是不正确的。

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

// ... your code

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

小提琴

hash 代码更改并不能证明创建了一个新实例 - 记录生成了GetHashCode ,其中将包含声明的字段(检查sharplab.io ),因此更改字段将导致 hash 代码更改。

所以回答你的问题:

使用反射,是否可以将值设置为多个属性而无需在每次赋值时创建新实例

是的,这是因为当您使用反射操作属性时没有创建新实例。

你想达到什么目的? 如果您查看C# 参考记录

您还可以创建具有可变属性和字段的记录:

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

理想情况下没有理由使用反射来设置这些属性

但是如果你想创建一个不可变的记录,你应该使用以下示例之一来这样做。

public record Person(string FirstName, string LastName);

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

然而,这并不妨碍使用反射。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM