c#中的结构体数组

本文关键字:数组 结构体 | 更新日期: 2023-09-27 18:05:22

我试图从用户使用数组的结构,然后打印它的输入:

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
    }
}
}

不幸的是,在输入所有数据后,我得到:

CA4.Program+StudentDetails
CA4.Program+StudentDetails
CA4.Program+StudentDetails
CA4.Program+StudentDetails
CA4.Program+StudentDetails

它不会崩溃,只是代替我输入的数据得到上面的5行。

我知道它不起作用的原因是我没有正确使用结构体,因为没有它们就没有问题。

谁能帮帮我,告诉我如何在上面的例子中正确使用结构体。由于

欢呼,

n1te

c#中的结构体数组

这是因为默认情况下ToString()返回一个类型名称,您必须自己为StudentDetails struct重写它:

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

顺便说一句,为什么你要使用struct和遗留数组?考虑使用class代替struct,使用Generic IList<StudentDetails>IDictionary<int, StudentDetails>代替array。因为遗留数组与struct(基本上是值类型)一起在每次向数组中添加项和在读取它时拆箱(object -> struct)时引入了装箱(struct ->对象)。

Console.WriteLine("{0} ", student[row, column]);的调用隐式地调用了StudentDetails结构体的ToString()方法,该方法在默认情况下只是写出结构体类型的名称。重写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);
    }
}

然而,更大的问题是,你正在设置5个不同的StudentDetails结构的属性…通过声明一个数组StudentDetails[,] student = new StudentDetails[5, 1];并要求用户在数组的不同点输入关于结构体的详细信息,即student[0, 0]然后student[1,0],你不是在制作一个StudentDetails对象并在其上设置属性,你创建了5个不同的 StudentDetails对象。

为什么要使用数组?如果您想让用户填写单个StudentDetails对象,只需执行

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

然后写出来:

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

这将使用你在StudentDetails结构中声明的ToString()方法。(ToString()在需要将对象转换为字符串时调用,您不必总是编写它)

其他人已经涵盖了ToString()的覆盖,所以我不会重复该信息。更重要的是,根据您的要求:

谁能告诉我如何在上面的例子中正确地使用结构体

参见MSDN:结构设计

首先,你的结构是可变的。不可变结构并不总是最好的解决方案,但应该考虑…看看我的一篇关于微软在字典类中使用结构体的文章。也就是说,我将确定基本需求:结构是否需要可变性?换句话说,在结构实例化之后,学生的名字、单元号或标记会改变吗?

第二,如果要求有一个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++;
}

注意:本例中不考虑异常处理;例如,超出数组的边界自增。

在前面的示例中,您可以在实例化之后更改StudentDetails结构体的任何属性。当不可变的

结构体更安全:
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;
    }
}

这需要更改将details对象添加到students数组的方式:

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++;
}

考虑结构的要求并适当设计

您需要适当地打印结构体的成员。我建议使用一种方法,在给定结构体(如

)的情况下为您执行打印操作
public void PrintStruct(StudentDetails stDetails)
{
    Console.WriteLine(stDetails.firstName);
    Console.WriteLine(stDetails.lastName);
    .... etc
}

或者创建一个类(这是c#)并覆盖ToString()方法来返回一个包含所有成员信息的字符串,您不需要修改主代码。

结构在c#中是可以使用的,但是当你需要数据表示而不仅仅是简单的数据传输时,你应该使用类。