在对象初始值设定项中使用后清除变量也会清除对象的属性吗?

Ric*_*ano 3 c# object

为什么在此代码运行后Tags属性为Book空?

class Program
{
    static void Main(string[] args)
    {
        List<Book> books = new List<Book>();
        List<String> tags = new List<String> {"tag1", "tag2", "tag3"};
        String title = "a title";
        books.Add(new Book
        {
            Title = title,
            Author = "an author",
            Tags = tags
        });
        Console.WriteLine("(" + title + ")");
        Console.WriteLine((books[0]).Tags.Count());

        title = String.Empty;
        tags.Clear();

        Console.WriteLine("(" + title + ")");
        Console.WriteLine((books[0]).Tags.Count());
    }
}
Run Code Online (Sandbox Code Playgroud)

代码Book:

public class Book
{
    public String Title { get; set; }
    public String Author { get; set; }
    public List<String> Tags { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

运行此代码输出

("a title")
3
()
0
Run Code Online (Sandbox Code Playgroud)

tagstitle通过参考在这里?重命名相应的属性会产生相同的输出.

编辑:

我只是意识到我的意思是每个Console.WriteLine语句都引用对象,而不仅仅是标签.我的意思是:

Book aBook = books[0];
Console.WriteLine("(" + aBook.Title + ")");
Console.WriteLine(aBook.Tags.Count());

title = String.Empty;
tags.Clear();

Console.WriteLine("(" + aBook.Title + ")");
Console.WriteLine(aBook.Tags.Count());
Run Code Online (Sandbox Code Playgroud)

如预期的那样,产出:

("a title")
3
("a title")
0
Run Code Online (Sandbox Code Playgroud)

但是因为我在最初的问题中犯了一个错误,所以我将其保留原样,因为title所引用的答案部分都引用了原始代码.

Ode*_*ded 5

List<T> 是一个引用类型,所以是的,你在这里得到了引用语义.

你需要一个指定副本tags,如果你想他们是独立的财产.

Tags = new List<string>(tags);
Run Code Online (Sandbox Code Playgroud)

  • @TimS.可变性和引用语义是完全不同的,并且是独立的.`string`是不可变的这一事实使得更难以观察到你正在处理引用作为观察两个变量引用同一对象这一事实的最简单方法的事实是改变该对象.仅仅因为一个对象是不可变的并不会使它"表现得像一个值".它的行为与引用完全相同,因为它是一个.模糊参考语义和可变性之间的界限只会使每一个理解得更难,而不是更容易. (2认同)