简体   繁体   English

c# foreach 循环列表与 class

[英]c# foreach loop list with class

Trying to display the names and student ID with a foreach loop at the end of the program, but instead of listing the names it just gives me the output "Assignment_8.Student".尝试在程序末尾使用 foreach 循环显示姓名和学生 ID,但它没有列出姓名,而是给了我 output“Assignment_8.Student”。 How exactly would I display the names and ID's instead of that directory its giving me?我将如何准确地显示名称和 ID 而不是它给我的那个目录?

using System;
using System.Collections.Generic;

namespace Assignment_8
{
class Program
{
    static void Main(string[] args)
    {

         List<Student> myList = new List<Student>();

        Student s1 = new Student();
        s1.FirstName = "John";
        s1.LastName = "Smith";
        s1.StudentID = 2560;
        myList.Add(s1);

        Student s2 = new Student("Peter");
        myList.Add(s2);


        Student s3 = new Student("Morgan", "Simmons");
        myList.Add(s3);

        Student s4 = new Student("James", "Walters");
        myList.Add(s4);

        Student s5 = new Student("Linda", "Scott", 1005);
        myList.Add(s5);


        Console.WriteLine();

        Console.WriteLine("Total students: {0}", Student.Count);

        foreach (var item in myList)
        {
            Console.WriteLine("Student: {0}", item);
        }
       
        
    }
}
}

Here is the Class:这是 Class:

using System;
using System.Collections.Generic;
using System.Text;

namespace Assignment_8
{
class Student
{
    public static int Count { get; private set; }
    private static readonly Random rnd = new Random();

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int StudentID { get; set; }
    

    public Student(string first, string last, int id)
    {
        FirstName = first;
        LastName = last;
        StudentID = id;
        ++Count;
        Console.WriteLine("Student Name: {0} {1}, Student ID: {2}",
            FirstName, LastName, StudentID );
    }

    public Student(string first ="", string last ="")
    {
        FirstName = first;
        LastName = last;
        ++Count;
        Console.WriteLine("Student Name: {0} {1}, Student ID: {2}",
           FirstName, LastName, rnd.Next(1000, 9999) );
    }

}
}

Here is the Output of the program:这是程序的Output:

Student Name:  , Student ID: 4101
Student Name: Peter , Student ID: 9074
Student Name: Morgan Simmons, Student ID: 2328
Student Name: James Walters, Student ID: 5481
Student Name: Linda Scott, Student ID: 1005

Total students: 5
Student: Assignment_8.Student
Student: Assignment_8.Student
Student: Assignment_8.Student
Student: Assignment_8.Student
Student: Assignment_8.Student

You need either to use the same approach as you do in constructors:您需要使用与构造函数中相同的方法:

    foreach (var item in myList)
    {
        Console.WriteLine("Student: {0} {1} {2}", item.StudentID, item.FirstName, item.LastName);
    }

Or to override ToString (otherwise class name will be used to convert class instance to string):或覆盖ToString (否则 class 名称将用于将 class 实例转换为字符串):

class Student
{
    public override string ToString()
    {
        return string.Format("Student: {0} {1} {2}", StudentID, FirstName, LastName);
    }
}

And usage in you loop:在你的循环中使用:

Console.WriteLine(item);

Also since C# 6 there you can beautify it with string interpolation :此外,由于 C# 6 在那里,您可以使用字符串插值来美化它:

    public override string ToString()
    {
        return $"Student: {StudentID} {FirstName} {LastName}";
    }

On this line here:在这条线上:

Console.WriteLine("Student: {0}", item);

item is an object of type Student. item是 Student 类型的 object。 Because Microsoft never wrote a WriteLine(string, Student) method that knows specifically how to print out one of your Students with its name and everything, the form of WriteLine that ends up getting used is WriteLine(string, object) .因为 Microsoft 从未编写过一个WriteLine(string, Student)方法,该方法专门知道如何打印出您的学生及其名称和所有内容,所以最终使用的 WriteLine 形式是WriteLine(string, object)

This form of WriteLine will use the first string as a format spec to create a custom string using the other objects passed in in plae of the numbered placeholders in the string.这种形式的 WriteLine 将使用第一个字符串作为格式规范,以使用在字符串中编号占位符中传入的其他对象来创建自定义字符串。 Because it needs the objects to be a string, it simply calls the .ToString() method on whatever thing is passed into it as the object argument, in this case a Student, when it is building the string to output from the format string "Student: {0}".因为它需要对象是一个字符串,所以它只需调用.ToString()方法对作为object参数传递给它的任何东西,在这种情况下是一个学生,当它从格式字符串构建字符串到 output 时学生:{0}”。

Because your Student doesn't have a specific version of the ToString() method, it uses the default one on the base object , from which Student is derived (everything inherits from object if it doesn't inherit from something more specific)因为您的 Student 没有特定版本的ToString()方法,所以它使用基础object上的默认版本,从中派生 Student (如果它没有从更具体的东西继承,则一切都继承自 object)

The ToString() method on object is very primitive: it merely returns the name of the kind of object it is, in this case a Assignment_8.Student object 上的ToString()方法非常原始:它仅返回 object 类型的名称,在本例中为Assignment_8.Student

The end result is that WriteLine(string, object) is processing the "Student: {0}" , string, it finds placeholder {0}, it goes to the 0th argument (the Student item ), calls ToString() on it, gets "Assignment_8.Student" back, pops it in the string "Student: {0}" in place of the {0} and then finishes its work最终结果是WriteLine(string, object)正在处理"Student: {0}"字符串,它找到占位符 {0},它转到第 0 个参数(学生item ),对其调用ToString() ,取回"Assignment_8.Student" ,将其弹出到字符串"Student: {0}"中代替 {0},然后完成其工作


To alter things you either need to:要更改内容,您需要:

  • Use a different flavor of WriteLine , such as WriteLine(string) , by making your string first, and passing the string you made into it:使用不同风格的WriteLine ,例如WriteLine(string) ,首先创建您的字符串,然后将您创建的字符串传递给它:
WriteLine(item.Firstname + " " + item.LastName) 
WriteLine($"{item.Firstname} {item.LastName}")

In this case it is the class that calls WriteLine that gets to decide how a student is to be displayed在这种情况下,调用 WriteLine 决定如何显示学生的是 class

  • Use this flavor of WriteLine that accepts a format and a bunch of parameter objects but give actual strings to the parameters: WriteLine("Student FN:{0}, LN:{1}", item.FirstName, item.LastName) - item.FirstName and item.LastName are actually strings that are part of the Student, rather than being the whole Student.使用这种风格的WriteLine ,它接受格式和一堆参数对象,但为参数提供实际字符串WriteLine("Student FN:{0}, LN:{1}", item.FirstName, item.LastName) - item.FirstNameitem.LastName实际上是属于 Student 的字符串,而不是整个 Student。 Even though these strings will also be passed in as objects, they're still strings at the core of their being, and calling .ToString on a string, returns the string itself, so everything works out尽管这些字符串也将作为对象传入,但它们仍然是其核心的字符串,并且在字符串上调用.ToString会返回字符串本身,因此一切正常
  • Create a version of the ToString() method in your Student class that returns a formatted representation of the student as a string.在 Student class 中创建一个ToString()方法版本,以字符串形式返回学生的格式化表示。 With this way, yourStudent goes in, has ToString() called on it, gets its chance to shine and return a pretty version of itself, and the result is inserted into the formatting string in place of {0}:通过这种方式,yourStudent 进入,调用了ToString() ,它有机会发光并返回一个漂亮的版本,并将结果插入到格式化字符串中以代替 {0}:
    class Student{
      override string ToString(){
        return this.LastName + ", " + this.FirstName;
      }
   }

There are some other more wacky things you could do, such as serializing to JSON, which will return a representation of the class suitable for computer consumption, but the basic thing here is that something needs to decide how your Student should be formatted and presented - and that's either the Student itself ( override ToString() way), or the thing that knows about the Student.您还可以做一些其他更古怪的事情,例如序列化为 JSON,这将返回适合计算机使用的 class 的表示,但这里的基本内容需要决定您的学生应该如何格式化和呈现 -这要么是学生本身( override ToString()方式),要么是了解学生的事情。

Arguably, you could say it should be the class that holds the Student rather than the Student itself, because the Student itself can't possibly know how to format itself in all the myriad ways different things might want to see it可以说,你可以说它应该是持有学生而不是学生本身的 class,因为学生本身不可能知道如何以不同的事物可能希望看到的各种方式来格式化自己

Simply update the foreach loop as:只需将 foreach 循环更新为:

Console.WriteLine("Student: {0}, {1}", item.FirstName, item.StudentID);

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

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