繁体   English   中英

C#类作为其他类变量,生存范围

[英]C# Class as other class variable, scope of live

我创建了一小段代码以测试项目的一部分。 它正在工作,但是我有一些疑问...

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

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

item = new Item();

正如您在代码中看到的那样,有两行是这样的,其中一行已注释,而另一行未注释。

  • Part_1:按原样执行代码时,每次调用“ AddBucketItem”方法时,它将创建一个“ Item”类的新实例,然后“ Item.SetItem”将设置“开始”,“结束”,“范围” '在'item'变量中,它将被添加到'ItemList'中。

  • 第2部分:当我要评论现有的“ item = new Item();”时 行和取消注释其他一个,那么我将期待以下内容。 创建BucketItem类的新实例时,它还将创建“ Item”的新实例,这是在“ BucketItem”构造函数中定义的。 然后,当调用“ AddBucketItem”方法时,“ item”变量将由“ item.SetItem”设置,然后添加到ItemList。 第一次迭代就可以。 但是,如果我再次使用新的“开始”和“结束”参数调用“ AddBucketItem”方法,这也会更改已添加的ItemList [0]。

  • 问题:

  • 为什么在Part_2中的每个调用都会更改已经添加到ItemList中的所有元素? 唯一的解释是列表中的所有元素都存储着对“ item”变量的引用,并且当通过更改(开始,结束,持续时间)更改此变量时,它还将更改所有ItemList。 但是我不知道这是正确的解释,还是我不知道为什么会这样。 但是,我假设答案是不同的,因为即使我做与“ 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()); } 

    有人可以请问我的问题吗?

在您的示例中, new_valint ,它是value类型
同时,在第一个代码段中, Item是一个类,它是引用类型

如果使用Part_2描述的Part_2 ,则实际上是对一个对象进行操作。 因此,您的ItemList包含N个项目,它们都是相同的对象。

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

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

您需要了解,在C#中,对象是通过引用传递的,而原始类型是通过值传递的。

因此,您对AddBucketItem示例的理解是正确的。 Item对象在BucketItems构造函数中仅创建一次。 调用AddBucketItem() ,您正在修改原始实例并将其引用添加到列表中。 因此,最后,您将获得一个列表,其中包含所有指向同一对象实例的单个项目。

对于您提供的第二个示例,它的行为有所不同,因为对于int类型(它是原始数据类型),传递给Add()函数的值是整数的副本,而不是引用。

暂无
暂无

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

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