首页 > 解决方案 > C# 属性值对某些是通过引用,对另一些是通过值

问题描述

我不确定下面代码的问题在哪里,一个类实例的值会改变另一个类实例的值。似乎我有类型类的问题属性,其中一个类中设置的值会影响同一类型的另一个类的值。示例如下。我想要实现的是在从一个类 (Result 2) 分配值之后,对另一个类的后续操作不会影响前一个类。

public class Address {
    public string Street {
        get;
        set;
    }
}

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

    public List<Address> Addresses { 
        get; 
        set; 
    } = new List<Address>();

    public int Age { 
        get; 
        set; 
    }
}

public class Employee {
    public string EmpID {
        get;
        set;
    }

    public Person EmployeePerson {
        get;
        set; 
    }
}

var emp = new Employee { 
    EmpID = "1", 
    EmployeePerson = new Person { 
        Name = "Alice", Addresses = 
        new List<Address> { 
            new Address { 
                Street = "123 Street" 
            }
        } 
    } 
};

var per = new Person { 
    Name = emp.EmployeePerson.Name, Addresses = emp.EmployeePerson.Addresses };

per.Addresses[0].Street = "New Street";
per.Name = "New Name";   

Console.WriteLine("Result 1: {0} , {1}", 
    emp.EmployeePerson.Name, per.Name);
    
Console.WriteLine("Result 2: {0} , {1}", 
    emp.EmployeePerson.Addresses[0].Street, per.Addresses[0].Street);

结果 1: Alice , 新名字

结果2:新街,新街

标签: c#

解决方案


List<T>是引用类型。在您的示例中,emp.EmployeePerson并且per都引用了同一个列表。如果您操作该列表,您将看到两个变量的变化。

per您可以通过在通过复制旧列表来初始化变量时创建一个新列表来避免这种情况。但Address也是引用类型,因此两个列表都将保存对同一实例的引用。您还必须复制地址变量。我Copy()在您的课程中添加了一个方法Address

var per = new Person { Name = emp.EmployeePerson.Name, Addresses = emp.EmployeePerson.Addresses.Select<Address,Address>(x => x.Copy()).ToList() };

public class Address
{
    public string Street {get;set;}
        
    public Address Copy()
    {
        return new Address { Street = this.Street };
    }
}

引用类型和值类型之间的区别在 C# 中非常重要。以下是官方文档中的一些信息:

https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/reference-types https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-types


推荐阅读