[英]Array of structs in C#
我正在嘗試使用結構數組從用戶那里獲取輸入,然后打印它:
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
這是因為默認情況下ToString()
返回一個類型名稱,您必須自己為StudentDetails
結構覆蓋它:
public struct StudentDetails
{
public override void ToString()
{
return String.Format(
CultureInfo.CurrentCulture,
"FirstName: {0}; LastName: {1} ... ",
this.FirstName,
this.LastName);
}
}
順便說一句,您為什么使用 stuct 和舊版 arrays? 考慮使用class
代替struct
,並使用通用IList<StudentDetails>
或IDictionary<int, StudentDetails>
代替數組。 因為傳統的 arrays 和 struct (基本上是值類型)在每次將項目添加到數組並在讀回時取消裝箱(object -> struct)時都會引入裝箱(struct -> object)。
您對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 object 並在其上設置屬性,您創建了 5 個不同的StudentDetails 對象。
你為什么使用數組? 如果要用戶填寫單個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();
...
然后寫出來:
Console.WriteLine("{0}", student);
這將使用您在 StudentDetails 結構中聲明的 ToString() 方法。 (只要需要將 object 轉換為字符串,就會調用 ToString(),您不必總是編寫它)
希望這可以幫助。
其他人已經覆蓋了ToString()
的覆蓋,所以我不會重復這些信息。 更重要的是,根據您的要求:
有人可以幫助我並告訴我如何在上面的示例中正確使用結構。
請參閱MSDN:結構設計
首先,您的結構是可變的。 不可變結構並不總是最好的解決方案,但應該考慮......請參閱我在 Microsoft 在 Dictionary class 中使用結構的帖子。 也就是說,我將確定基本要求:結構是否需要可變性? 換句話說,在結構實例化之后,學生的姓名、單元編號或標記會發生變化嗎?
其次,如果要求有一個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;
}
}
這需要更改將詳細信息 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++;
}
適當考慮結構和設計的要求。
您需要適當地打印結構的成員。 我會建議一種為您打印的方法,給定一個結構,例如
public void PrintStruct(StudentDetails stDetails)
{
Console.WriteLine(stDetails.firstName);
Console.WriteLine(stDetails.lastName);
.... etc
}
或者,創建一個 Class(這是 C#)並覆蓋 ToString() 方法以返回包含所有成員信息的字符串,您無需修改主代碼。
結構體可以在 C# 中使用,但如果您需要數據表示而不是簡單的數據傳輸,則應該使用 class。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.