Массив структур в 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

4 ответов


вызов Console.WriteLine("{0} ", student[row, column]); неявно вызывает метод ToString () структуры StudentDetails, который по умолчанию просто записывает имя типа структуры. Переопределите метод 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);

это будет использовать метод ToString (), который вы объявили в своей структуре StudentDetails. (Метод toString() вызывается, когда объект должен быть преобразован в строку, вы просто не всегда приходится это писать)

надеюсь, что это помогает.


это потому что по умолчанию ToString() возвращает имя типа, вы должны переопределить его для себя StudentDetails struct:

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> вместо массива. Поскольку устаревшие массивы вместе со структурой (в основном тип значения) вводят бокс (struct -> object) каждый раз, когда вы добавляете элемент в массив и распаковываете (object -> struct) при его чтении.


другие покрыли переопределение ToString(), поэтому я не буду пересказывать эту информацию. Тем более, на ваш запрос:

может кто-нибудь, пожалуйста, помогите мне и скажите мне, как использовать структуры propely в примере выше.

посмотреть MSDN: конструкция структуры

во-первых, ваша структура изменчива. Неизменяемые структуры не всегда являются лучшие решение, но должно быть рассмотрено ...см. сообщение, которое у меня есть Используйте Microsoft о структуры внутри класса словарь. Тем не менее, я бы определил основное требование: требует ли структура изменчивости? другими словами, изменится ли имя студента, номер единицы или метка после создания экземпляра структуры?

во-вторых, если требование состоит в том, чтобы иметь коллекцию 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#, но в случаях, когда вам нужно представление данных, а не просто простая передача данных, чем вы должен использовать класс.