简体   繁体   English

C# 中的结构数组

[英]Array of structs in C#

I'm trying to get input from user using array of structs and then print it:我正在尝试使用结构数组从用户那里获取输入,然后打印它:

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

namespace CA4
{
class Program
{
    static void Main(string[] args)
    {
        StudentDetails[,] student = new StudentDetails[5, 1];

        Console.WriteLine("Please enter the unit code:");
        student[0, 0].unitCode = Console.ReadLine();

        Console.WriteLine("Please enter the unit number:");
        student[1, 0].unitNumber = Console.ReadLine();

        Console.WriteLine("Please enter first name:");
        student[2, 0].firstName = Console.ReadLine();

        Console.WriteLine("Please enter last name:");
        student[3, 0].lastName = Console.ReadLine();

        Console.WriteLine("Please enter student mark:");
        student[4, 0].studentMark = int.Parse(Console.ReadLine());

        for (int row = 0; row < 5; row++)
        {
            Console.WriteLine();
            for (int column = 0; column < 1; column++)
                Console.WriteLine("{0} ", student[row, column]);
        }

        Console.ReadLine();
    }

    public struct StudentDetails
    {
        public string unitCode; //eg CSC10208
        public string unitNumber; //unique identifier
        public string firstName; //first name
        public string lastName;// last or family name
        public int studentMark; //student mark
    }

}
}

Unfortunately after entering all the data I get:不幸的是,在输入我得到的所有数据后:

CA4.Program+StudentDetails

CA4.Program+StudentDetails

CA4.Program+StudentDetails

CA4.Program+StudentDetails

CA4.Program+StudentDetails

It doesn't crash, just instead of the data that I entered get the above 5 lines.它不会崩溃,只是我输入的数据不是上面的 5 行。

I know that the reason why it doesn't work is that I don't use the structs correctly because without them there is no problem.我知道它不起作用的原因是我没有正确使用结构,因为没有它们就没有问题。

Can somebody please help me and tell me how to use structs propely in the example above.有人可以帮助我并告诉我如何在上面的示例中正确使用结构。 Thanks谢谢

Cheers,干杯,

n1te n1te

This is because by default ToString() returns a Type name, you've to override it yourself for StudentDetails struct:这是因为默认情况下ToString()返回一个类型名称,您必须自己为StudentDetails结构覆盖它:

public struct StudentDetails
{    
  public override void ToString()
  {
     return String.Format(
                CultureInfo.CurrentCulture,
               "FirstName: {0}; LastName: {1} ... ", 
                this.FirstName,
                this.LastName);
  }
}

BTW, why you are using stuct and legacy arrays?顺便说一句,您为什么使用 stuct 和旧版 arrays? Consider using class instead struct , and Generic IList<StudentDetails> or IDictionary<int, StudentDetails> instead of array.考虑使用class代替struct ,并使用通用IList<StudentDetails>IDictionary<int, StudentDetails>代替数组。 Because legacy arrays together with struct (basically value type) introduces a boxing (struct -> object) each time you've adding item to array and unboxing (object -> struct) when reading it back.因为传统的 arrays 和 struct (基本上是值类型)在每次将项目添加到数组并在读回时取消装箱(object -> struct)时都会引入装箱(struct -> object)。

Your call to Console.WriteLine("{0} ", student[row, column]);您对Console.WriteLine("{0} ", student[row, column]);的调用is implicitly calling the ToString() method of the StudentDetails struct, which just writes out the name of the struct type by default.是隐式调用 StudentDetails 结构体的 ToString() 方法,默认只写出结构体类型的名称。 Override the ToString() method:覆盖 ToString() 方法:

public struct StudentDetails
{
    public string unitCode; //eg CSC10208
    public string unitNumber; //unique identifier
    public string firstName; //first name
    public string lastName;// last or family name
    public int studentMark; //student mark

    public override string ToString()
    {
        return string.Format("{0},{1},{2},{3},{4}", unitCode,
               unitNumber,firstName,lastName,studentMark);
    }
}

However, the larger issue is that you are setting the properties of 5 different StudentDetails structs... by declaring an array StudentDetails[,] student = new StudentDetails[5, 1];但是,更大的问题是您正在设置 5 个不同 StudentDetails 结构的属性...通过声明一个数组StudentDetails[,] student = new StudentDetails[5, 1]; and asking the user to input details about the structs at different points in the array, ie student[0, 0] then student[1,0] , you aren't making one StudentDetails object and setting properties on it, you created 5 different StudentDetails objects.并要求用户输入有关数组中不同点的结构的详细信息,即student[0, 0]然后student[1,0] ,您没有制作一个 StudentDetails object 并在其上设置属性,您创建了 5 个不同的StudentDetails 对象。

Why are you using an array?你为什么使用数组? If you want to the user to fill in a single StudentDetails object, just do如果要用户填写单个StudentDetails object,只需

StudentDetails student = new StudentDetails();

Console.WriteLine("Please enter the unit code:");
student.unitCode = Console.ReadLine();

Console.WriteLine("Please enter the unit number:");
student.unitNumber = Console.ReadLine();

...

Then to write it out:然后写出来:

Console.WriteLine("{0}", student);

This will use the ToString() method you declared in your StudentDetails struct.这将使用您在 StudentDetails 结构中声明的 ToString() 方法。 (ToString() is called whenever an object needs to be converted to a string, you just don't always have to write it) (只要需要将 object 转换为字符串,就会调用 ToString(),您不必总是编写它)

Hope this helps.希望这可以帮助。

Others have covered the override of ToString() , so I won't rehash that information.其他人已经覆盖了ToString()的覆盖,所以我不会重复这些信息。 More so, to your request:更重要的是,根据您的要求:

Can somebody please help me and tell me how to use structs propely in the example above.有人可以帮助我并告诉我如何在上面的示例中正确使用结构。

See MSDN: Structure Design请参阅MSDN:结构设计

First, your struct is mutable.首先,您的结构是可变的。 Immutable structs are not always the best solution but should be considered...see a post I have on Microsoft's use of structs inside the Dictionary class .不可变结构并不总是最好的解决方案,但应该考虑......请参阅我在 Microsoft 在 Dictionary class 中使用结构的帖子 That said, I would determine the basic requirement: Does the struct require mutability?也就是说,我将确定基本要求:结构是否需要可变性? In other words, will the student's name, unit number, or mark change after struct instantiation?换句话说,在结构实例化之后,学生的姓名、单元编号或标记会发生变化吗?

Second, if the requirement is to have a collection of StudentDetails , an array is fine:其次,如果要求有一个StudentDetails的集合,一个数组就可以了:

//    declare students collection
StudentDetail[] students = new StudentDetail[5];
//    declare an array indexer
int indexer = 0;

static void Main(string[] args)
{
    Console.WriteLine("Please enter the unit code:");
    string unitCode = Console.ReadLine();

    Console.WriteLine("Please enter the unit number:");
    string unitNumber = Console.ReadLine();

    /*    get the rest of your inputs    */

    AddStudentDetails(unitCode, unitNumber, firstName, lastName, studentMark);
}

//    demonstrate auto-magically instantiated, mutable struct
void AddStudentDetails(string unitCode, string unitNumber, string firstName, string lastName, int studentMark)
{
    students[indexer].unitCode = unitCode;
    students[indexer].unitNumber = unitNumber;
    students[indexer].firstName = firstName;
    students[indexer].lastName = lastName;
    students[indexer].studentMark = studentMark;

    //    increment your indexer
    indexer++;
}

Note: exception handling is not considered in this example;注意:本例不考虑异常处理; eg, incrementing beyond the bounds of the array.例如,递增超出数组的范围。

In the previous example, you could change any of the properties of the StudentDetails struct after instantiation.在前面的示例中,您可以在实例化后更改StudentDetails结构的任何属性。 Structs are made more safe when immutable:结构在不可变时变得更加安全

public struct StudentDetails
{
    public readonly string unitCode; //eg CSC10208
    public readonly string unitNumber; //unique identifier
    public readonly string firstName; //first name
    public readonly string lastName;// last or family name
    public readonly int studentMark; //student mark

    //    use a public constructor to assign the values: required by 'readonly' field modifier
    public StudentDetails(string UnitCode, string UnitNumber, string FirstName, string LastName, int StudentMark)
    {
        this.unitCode = UnitCode;
        this.unitNumber = UnitNumber;
        this.firstName = FirstName;
        this.lastName = LastName;
        this.studentMark = StudentMark;
    }
}

This requires a change in how you add the details object to the students array:这需要更改将详细信息 object 添加到学生数组的方式:

void AddStudentDetails(string unitCode, string unitNumber, string firstName, string lastName, int studentMark)
{
    students[indexer] = new StudentDetails(unitCode, unitNumber, firstName, lastName, studentMark);

    //    increment your indexer
    indexer++;
}

Consider the requirements for the struct and design appropriately.适当考虑结构和设计的要求。

You need to print the members of the struct appropriately.您需要适当地打印结构的成员。 I would suggest a method that does the printing for you given a struct such as我会建议一种为您打印的方法,给定一个结构,例如

public void PrintStruct(StudentDetails stDetails)
{
    Console.WriteLine(stDetails.firstName);
    Console.WriteLine(stDetails.lastName);
    .... etc
}

Alternatively create a Class (This is C#) and override the ToString() method to return a string with all the member information and you won't need to modify your main code.或者,创建一个 Class(这是 C#)并覆盖 ToString() 方法以返回包含所有成员信息的字符串,您无需修改主代码。

Structs are all right to use in C# but in cases where you need data representation rather than just simple data transfer than you should use a class.结构体可以在 C# 中使用,但如果您需要数据表示而不是简单的数据传输,则应该使用 class。

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

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