【问题标题】:create list of objects without using list method or library. c#在不使用列表方法或库的情况下创建对象列表。 C#
【发布时间】:2022-01-13 22:05:11
【问题描述】:

我的情况

  • 仅使用类创建对象列表

这就是代码的工作原理

  • 使用ListRatings 类,我可以创建Rating 列表(不使用c# 库System.Collections.Generic 提供的列表方法)

(你可以在下面的代码中看到哪些属性和方法有类ListRatings和类Rating

问题

当我尝试打印我添加到列表中的所有评分时,我的程序只打印第一个和最后一个!

我的代码

类 ListRating:

public class ListRatings
{
    private Rating first;
    private Rating last;

    public ListRatings()
    {
        first = null;
        last = null;
    }
    public void InsertNewRat(Rating rating)
    {
        if (first == null)
        {
            first = rating;
            last = rating;
        }
        else
        {
            first.setNext(rating);
            last.setNext(rating);
        }
    }
    public void PrintRats()
    {
        Rating e = first;

        Console.WriteLine(e.getMatter());
        Console.WriteLine(e.getDate());
        Console.WriteLine(e.getRate());

        e = e.getNext();

        Console.WriteLine(e.getMatter());
        Console.WriteLine(e.getDate());
        Console.WriteLine(e.getRate());

        e = e.getNext();

        Console.WriteLine(e.getMatter());
        Console.WriteLine(e.getDate());
        Console.WriteLine(e.getRate());

    }
}

班级评分:

public class Rating
{
    private int rate;
    private string matter;
    private DateTime date;
    private Rating next;

    public Rating(int rate, string matter, DateTime date)
    {
        this.rate = rate;
        this.matter = matter;
        this.date = date;
        next = null;
    }

    public int getRate()
    {
        return rate;
    }

    public string getMatter()
    {
        return matter;
    }

    public DateTime getDate()
    {
        return date;
    }

    public Rating getNext()
    {
        return next;
    }

    public void setNext(Rating valutazione)
    {
        next = valutazione;
    }
}

主要:

    static void Main(string[] args)
    {
        ListRatings lr = new ListRatings();
        Rating r1 = new Rating(9, "Math", new DateTime(2021, 10, 5));
        Rating r2 = new Rating(10, "sport", new DateTime(2021, 11, 3));
        Rating r3 = new Rating(6, "English", new DateTime(2021, 11, 7));

        lr.InsertNewRat(r1);
        lr.InsertNewRat(r2);
        lr.InsertNewRat(r3);

        lr.PrintRats();
        Console.ReadKey();

    }

输出

Math
05/10/2021 00:00:00
9
English
07/11/2021 00:00:00
6

程序停止并说错误:System.NullReferenceException [在第二个e.getNext(); 我在类ListRating 中使用]

通过此输出,您可以看到正在打印第一个并跳转到最后一个而不打印第二个。

我需要的输出是

Math
05/10/2021 00:00:00
9
Sport
10
03/11/07 00:00:00
English
07/11/2021 00:00:00
6

对不起我的英语不好

【问题讨论】:

  • 你检查过这个实现的链表吗? geeksforgeeks.org/linked-list-implementation-in-c-sharp
  • 与标准列表相比,链表有什么好处?
  • 我们的老师让我们去做,我的意思是它一点也不差。当我们可以用简单的方式做某事时,我们经常用困难的方式做某事,但这就像训练一样。也为此:链表是对象的有序集合。那么是什么让它们与普通列表不同呢?链表与列表的不同之处在于它们在内存中存储元素的方式。列表使用连续的内存块来存储对其数据的引用,而链表将引用存储为它们自己元素的一部分。
  • 一个优点是,从一个适度大的链表中间插入或删除元素会更快,因为您更新指针而不是复制可能很大的内存块。

标签: c# list class oop


【解决方案1】:

您没有正确更新您的链接列表。这段代码:

else
{
    first.setNext(rating);
    last.setNext(rating);
}

始终将第一个和最后一个节点的下一个节点设置为您尝试插入的那个。

相反,你想要

else
{
    last.setNext(rating);
    last = rating;
}

这会将当前最后一个节点设置为新节点,然后将指向最后一个节点的指针更新为评级,该节点现在应该是链表中的最后一个。

至于 NullReferenceException,@TheVillageIdiot 是正确的

【讨论】:

  • 我运行它并得到了你期望的输出......
【解决方案2】:

你可以调整这个解决方案:

class Program
{
    static void Main(string[] args)
    {
        var list = new List<int>();
        list.Append(1);
        list.Append(2);
        list.Append(3);
        list.Append(4);
        list.Append(5);

        list.Print();

        var list2 = new List<int>(11, 22, 33);
        list.Concat(list2);
        list.Print();
    }
}

public class List<T>
{
    Node<T> first;
    Node<T> last;

    public List()
    {

    }

    public List(params T[] data)
    {
        Append(data);
    }

    public void Append(params T [] data)
    {
        foreach (T d in data)
        {
            var n = new Node<T> { data = d };
            if (last == null)
            {
                first = n;
                last = n;
            }
            else
            {
                last.next = n;
                last = n;
            }
        }
    }

    public void Concat(List<T> list)
    {
        if (last == null)
        {
            first = list.first;
            last = list.last;
        }
        else
        {
            last.next = list.first;
            last = list.last;
        }
    }

    public void Print() 
    {
        var n = first;
        while (n != null)
        {
            Debug.Write(n.data);
            if (n.next != null)
                Debug.Write(" -> ");

            n = n.next;
        }
        
        Debug.WriteLine("");
    }
}

public class Node<T>
{
    public T data { get; set; }
    public Node<T> next { get; set; }
}

【讨论】:

  • 我需要的解决方案是不使用列表方法。 (有可能)
  • 只需将“List”更改为“MyList”,将“List”更改为“MyList”...
  • 我没明白。我不是指名称,而是列表方法。换句话说,我的代码不必包含类似的内容: list...
  • 我的 List 类是我自己的类,而不是 .NET List 类。您可以随意重命名它,这就是重点。从 Rating 类中删除 next(),而不是像这样创建列表:var rating = new MyList()。等等……
  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
【解决方案3】:

您正在尝试创建一个链表实现。不确定您的RatingsList 课程中是否需要last。就个人而言,我也会将first 重命名为rating。问题是您如何迭代 PrintRats 函数中的评级。改成这个然后试试:

public void PrintRats()
{
    Rating e = first;
    
    while(e!=null)
    {
        Console.WriteLine(e.getMatter());
        Console.WriteLine(e.getDate());
        Console.WriteLine(e.getRate());

        e = e.getNext();
    }
}

此外,您可以将上述方法中的所有Console.WriteLine 移动到Rating 类中。最后,命名方法PrintRats 而不是PrintRatings 并不简洁。

PS:如果我听起来很暴躁,这还是早茶之前。

【讨论】:

  • 我使用许多控制台写行而不是循环来帮助设计我糟糕的英语。所以前 3 行是输出等的前 3 行...
  • 使用您的代码我没有收到错误,但程序仍然只打印第一个和最后一个
猜你喜欢
  • 2015-03-17
  • 1970-01-01
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多