C#类作为其他类变量,活动范围

pho*_*nix 1 c# scope class list

我创建了一小段代码来测试我的项目的一部分.它工作但我有一些问题......

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace testtodel
{
    class Program
    {
        private class BucketItems
        {
            private List<Item> ItemList;
            private Item item;

            public BucketItems()
            {
                //item = new Item();
                ItemList = new List<Item>();
            }

            public void AddBucketItem(int _Start, int _End)
            {
                    item = new Item();
                    item.SetItem(_Start, _End);
                    ItemList.Add(item);
            }

            public void PrintItemList()
            {
                for (int i = 0; i < ItemList.Count(); i++)
                {
                    Console.WriteLine("Item: " + i.ToString() + " S: " + ItemList[i].Start.ToString() + " E: " + ItemList[i].End.ToString() + " D: " + ItemList[i].Range.ToString());
                }
            }
        }

        private class Item
        {
            public int Range { get; set; }
            public int Start { get; set; }
            public int End { get; set; }

            public void SetItem(int _Start, int _End)
            {
                Start = _Start;
                End = _End;
                Range = _End - _Start;
            }
        }

        static void Main(string[] args)
        {
            BucketItems bucketItems = new BucketItems();
            bucketItems.AddBucketItem(0, 100);
            bucketItems.AddBucketItem(200, 300);
            bucketItems.AddBucketItem(700, 1000);
            bucketItems.PrintItemList();
            Console.ReadLine();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不完全理解的东西与线有关

item = new Item();

正如你在代码中看到的那样,有两行代表,一篇注释,一篇未注释.

  • Part_1:当代码按原样执行时,每当调用'AddBucketItem'方法时,它将创建一个'Item'类的新实例,然后'Item.SetItem'将设置'Start','End','Range ''item'变量,这将被添加到'ItemList'.

  • Part_2:当我评论现有的'item = new Item();' 排队并取消注释其他人然后我会期待以下.当创建BucketItem类的新实例时,它还将创建一个'Item'的新实例,因为它在'BucketItem'构造函数中定义.然后,当调用'AddBucketItem'方法时,'item'SetItem'将设置'item'变量,然后添加到ItemList.这对第一次迭代来说是可以的.但是,如果我再次调用'AddBucketItem'方法,使用新的'Start'和'End'参数,这也将改变已添加的ItemList [0].

  • 问题:

  • 为什么Part_2中的每个调用都会更改已添加到ItemList的所有元素?唯一的解释是列表中的所有元素都存储对'item'变量的引用,当通过更改(Start,End,Duriation)更改此变量时,它也将更改所有ItemList.但我不知道这是否是正确的解释,如果是,我不知道它为什么会这样.Hovever我假设答案是不同的,因为下面的例子将按预期填充列表,即使我正在做与'Part2'完全相同的事情.我有变量,我正在改变变量的值,我正在添加这个变量列出.

        int new_val;
        List<int> _lst = new List<int>();
        for (int i = 0; i < 10; i++)
        {
            new_val = i;
            _lst.Add(new_val);
        }
            for (int i = 0; i < _lst.Count(); i++)
        { Console.WriteLine("ListIdx: " + i.ToString() + " Value: " + _lst[i].ToString()); } 
    
    Run Code Online (Sandbox Code Playgroud)

    有人可以对我的问题有所了解吗?

Yel*_*yev 5

在你的榜样,new_val是int这是值类型.
同时,在第一个代码片段中,Item是一个类,它是引用类型.

如果您使用描述的方法Part_2,那么您实际上使用一个对象.所以,你ItemList包含N个项目,它们都是同一个对象.

在Part_1每次调用时AddBucketItem,您都会创建一个新对象并将其附加到列表中.在Part_2每次调用时AddBucketItem,您都可以修改单个原始Item对象.

您可能希望在MSDN上阅读有关值类型和引用类型的一些信息:https://msdn.microsoft.com/en-us/library/4d43ts61(v = vs.90)
.aspx