【问题标题】:How to chain Objects in C#如何在 C# 中链接对象
【发布时间】:2019-09-28 08:16:55
【问题描述】:

我有 4 个问题:

  1. 我怎么可能打印 Console.WriteLine(list.head.Next.Next.Data)。 从 AddHead() 开始,新对象将保存在前一个对象之上 n.Next?

  2. 我创建了一个自定义类来尝试了解上面的示例是否只是特定于列表的。 那么,我怎么可能 Console.WriteLine(cc.head.Next.Next.Next.Data) ?

  3. 如何在论坛的盒子里贴代码,这是我第一次发帖,请见谅。

谢谢!

using System;

namespace GenericInterfaces
{
    class Program
    {
        static void Main()
        {
            //Declare and instantiate a new generic SortedList class.
            //Person is the type argument.
            SortedList<Person> list = new SortedList<Person>();

            //Create name and age values to initialize Person objects.
            string[] names = new string[]
            {
            "Franscoise",
            "Bill",
            "Li",
            "Sandra",
            "Gunnar",
            "Alok",
            "Hiroyuki",
            "Maria",
            "Alessandro",
            "Raul"
            };

            int[] ages = new int[] { 45, 19, 28, 23, 18, 9, 108, 72, 30, 35 };

            //Populate the list with new Node Objects
            for (int x = 0; x < 10; x++)
            {
                //ages[x] is integer
                list.AddHead(new Person(names[x],ages[x]));
            }

            //Print out unsorted list.
            foreach (var p in list)
            {
                System.Console.Write(p.ToString() + " ");
                Console.WriteLine("Unsorted Data");
                Console.WriteLine(list.head.Data);
                Console.WriteLine(list.head.Next.Data);
                Console.WriteLine(list.head.Next.Next.Data);
                Console.WriteLine(list.head.Next.Next.Next.Data);

            }
            System.Console.WriteLine("Done with unsorted list");


            Console.WriteLine("My Custom Class Experiment");
            MyCustomClass cc = new MyCustomClass();
            for (int i = 0; i < ages.Length; i++)
            {
                cc.AddHead(ages[i]);
            }
            Console.WriteLine("Added ages to custom class");
            Console.WriteLine(cc.head.Data);
            Console.WriteLine(cc.head.Next.Data);
            Console.WriteLine(cc.head.Next.Next.Data);
            Console.WriteLine(cc.head.Next.Next.Next.Data);
            Console.WriteLine(cc.head.Next.Next.Next.Next.Data);
            Console.WriteLine(cc.n.Data);
            Console.WriteLine(cc.n.Next.Data);

        }
    }
    //Type parameter T in angle brackets.
    public class GenericList<T> : System.Collections.Generic.IEnumerable<T>
    {
        public Node head;
        public Node current = null;

        // Nested class is also generic on T
        public class Node
        {
            public Node Next { get; set; } = null;
            public T Data { get; set; }

            public Node(T t)  //T used in non-generic constructor
            {
                Data = t;
            }
        }

        public GenericList()  //constructor
        {
            head = null;
        }

        public void AddHead(T t)  //T as method parameter type
        {
            Node n = new Node(t);
            n.Next = head;
            head = n;
        }

        // Implementation of the iterator
        public System.Collections.Generic.IEnumerator<T> GetEnumerator()
        {
            Node current = head;
            while (current != null)
            {
                yield return current.Data;
                current = current.Next;
            }
        }

        // IEnumerable<T> inherits from IEnumerable, therefore this class 
        // must implement both the generic and non-generic versions of 
        // GetEnumerator. In most cases, the non-generic method can 
        // simply call the generic method.
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
    public class MyCustomClass
    {
        public Mode head;
        public Mode current = null;
        public Mode n;

        // Nested class is also generic on T
        public class Mode
        {
            //public Mode Next { get; set; } = null;
            public Mode Next;
            public int Data { get; set; }

            public Mode(int t)  //T used in non-generic constructor
            {
                Data = t;
            }
        }

        public void AddHead(int t)  //T as method parameter type
        {
            n = new Mode(t);
            n.Next = head;
            head = n;
        }
    }

【问题讨论】:

  • 我格式化了代码。如果您愿意,可以通过单击帖子下方的“已编辑”链接来比较两个版本。 (代码通过将所有内容缩进 4 个空格来标记。标记代码并单击顶部的 {}symbol 即可。)
  • 您好 Peter A. Schneider,感谢您的评论,以后会试一试!

标签: c# object reference


【解决方案1】:

新对象将保存前一个对象 n.Next?

在 LinkedList 中,列表节点的 Next 属性不会保存或操作有关列表的任何内容,它只是返回节点指向的 Next 项。返回的项目也是一个节点,它有自己的 Next,它指向列表中的另一个项目。如果您反复调用 Next,那么您只需沿着列表移动

把它想象成试图找到你的孩子。你知道他去了约翰家。你去约翰家,但被告知“他们去了保罗家”,所以你去了保罗家,被告知“他们去了莎拉家”,所以你去了莎拉家……

在每一步,你都会被送到下一个房子,但你不会拆除任何人的房子。您会记住您在房屋列表中的位置。如果您回到 johns house 并重新开始(列表头),您将再次走同一条路线

如果您要创建一个指向列表头部的新变量,然后反复将其重新分配给 Next,那么您始终会更改临时变量指向的节点,但列表节点本身始终保持指向彼此也一样,而且你不要打扰他们的关系:

var tempNode = list.Node; //tempNode is you, you’re at john’s house now
tempNode = tempNode.Next; //now you’re at paul’s house
tempNode = tempNode.Next; //now you’re at sarah’s 

您从未打扰任何现有节点。如果,当你到达保罗家时,你对保罗的父亲说“如果我妻子来问,告诉她我儿子去了简家”——这会改变保罗的父亲指向下一个人的地方:

var tempNode = list.Node; //tempNode 是你,你现在在约翰家 tempNode = tempNode.Next; //现在你在保罗家 tempNode.Next = new Node(“简家”);

现在我们实际上已经操作了列表并改变了第二个节点的 Next 指向的位置

AddHead 是如何工作的?

它获取你传入的数据并从中创建一个新节点,然后使新节点的 Next 指向现有列表头,并使现有列表头指向新节点。这有效地使列表通过一直添加新头来向后增长。如果您希望按照 John、Paul、Sarah 的顺序访问这些房屋,则必须按照 AddHead(Sarah), AddHead(Paul), AddHead(John)

的顺序添加它们

列表增长如下:

head->nothing 

head->Sarah

head->Paul->Sarah

head->John->Paul->Sarah

我简化了它的外观,隐藏了节点和下一步。每一个箭头-&gt;代表Next,每一个名字都是Node里面的Data

我如何发布代码

在代码块前后分别放置 3 个反引号。或者在代码的每一行前面加上 4 个或更多的空格

我应该如何命名问题

这真的由您决定,因为它可以帮助我们了解您的想法以及问题主体

【讨论】:

  • 好比喻!您可以进行纸质追逐或寻宝游戏,在每个房屋中放置一个标有“下一个”的框,该框可能是空的(在 C# 中为空)或包含下一个房屋的引用(即地址 ;-))。
  • 嗨,Caius Jard,我还是有些难以理解。这是我的想法。每次调用 AddHead() 时,都会创建一个新的 Node() 或 Mode 对象。并且,作为对象的属性的下一个将被分配上一个对象。这是我感到困惑的地方。我们是否使用 AddHead() 创建单个对象并分配 Next 属性。还是我们每次调用 AddHead() 时都创建一个新对象。而且,这种解释是否适用于 CustomClass 和 GenericList
  • 换句话说,跟随你的故事。当我第一次调用 AddHead() 时,我正在使用属性 Next 来创建 John house,它是 paul house。我第二次调用 AddHead() 时,我正在使用属性 Next 来创建 Paul House,即 Sarah house。所以如果我打电话给 Next.Next 我实际上是打电话给 Paul.SarahHouse?
  • 非常感谢Caius Jard 的详细解释!欣赏!
  • 没问题。我忘了补充,这个 Next.Next.Next 并不是真正的魔法,它只是引用其他对象的对象。假设如果我们改变了事情,那么在你的房子里,在你的街道上,在你的城市里,在你的国家里,那么如果我提到你,我可以通过youPerson.House.Street.City.Country 到达你的国家 - 这只是他们的清单'都是同一种对象,相互引用,所以访问下一个引用的对象总是相同的名称
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
相关资源
最近更新 更多