2011-08-13 150 views
6

我試圖使用結構的數組從用戶那裏得到輸入,然後打印:陣列結構的

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

回答

3

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

然而,更大的問題是,你通過聲明數組StudentDetails[,] student = new StudentDetails[5, 1];設置5層不同的StudentDetails結構...屬性,並在要求用戶輸入信息有關結構數組中的不同點,即student[0, 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(),您並不總是必須編寫它)

希望這有助於。

+0

首先感謝大家的快速響應 說實話,我不必在這裏使用數組,但下一個任務是相似的,我需要在那裏使用數組,所以我想來練習。 在接下來的任務,我必須接受的數據爲: 週數, 主隊名, 客隊名, 勝(1或0) _italic_Your程序必須使用結構數組/ s的存儲數據在內存中,即你的程序必須將文件中的數據作爲結構數組讀取到內存中,並操作數組中的數據。 總共有5周和80場比賽(有16支隊伍) – n1te

+0

這就是爲什麼我想我會在這裏放棄它,所以在下一個任務中更容易。 @Nick Bradley – n1te

+1

這很好,只要你明白,在你發佈的原始代碼中,你沒有填充一個StudentDetails結構體 - 你填寫了五個不同的結構體,但是你只填寫了unitCode第一個(在[0,0])unitNumber在第二個([1,0])第三名在第三..等你沒有完全填寫你所做的任何StudentDetails結構。 –

1

,需要相應地打印結構的成員。你給出一個struct如

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

或者創建一個類,我建議做印刷的方法(這是C#)和重寫ToString()方法的所有成員信息返回一個字符串,你將不需要修改你的主代碼。

在C#中使用結構都是正確的,但是在需要數據表示而不僅僅是簡單數據傳輸的情況下,應該使用類。

+0

*「但在需要數據表示而不是簡單的數據傳輸的情況下,應該使用類。」* ...並非總是如此。 ;) – IAbstract

+0

在大多數情況下:p –

5

這是因爲默認情況下ToString()返回類型名稱,你自己重載它StudentDetails結構:

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

順便說一句,你爲什麼使用stuct和傳統的陣列?考慮使用class代替struct,並使用通用IList<StudentDetails>IDictionary<int, StudentDetails>代替陣列。 由於遺留數組和結構(基本上是值類型)每次在讀取數據時將項添加到數組和拆箱(對象 - >結構)時都會引入一個裝箱(結構 - >對象)。

+3

Minor nitpick:字符串生成器是很多沒有收穫的工作。只需使用串聯或一個'string.Format()'。 – siride

+0

@siride:好點,謝謝 – sll

2

其他人已覆蓋ToString()的覆蓋,所以我不會重複這些信息。更多,所以,根據您的要求:

有人可以請幫助我,告訴我如何在上面的例子中使用結構。

MSDN: Structure Design

首先,你的結構是可變的。不可變的結構並不總是最好的解決方案,但應該考慮......請參閱我對微軟使用structs inside the 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; 
    } 
} 

這就要求你怎麼加改變的細節反對學生數組:

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

考慮的結構和設計適當的要求。

+0

非常感謝您的回答,這將使我的生活在下一次任務中變得更加輕鬆。順便說一句。保持要求的好處,會做:) – n1te