Массив структур в C # - PullRequest
       10

Массив структур в C #

6 голосов
/ 13 августа 2011

Я пытаюсь получить ввод от пользователя, используя массив структур, а затем распечатать его:

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 ]

5 голосов
/ 13 августа 2011

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

3 голосов
/ 13 августа 2011

Ваш вызов 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 () вызывается всякий раз, когда объект должен быть преобразован в строку, вы просто не всегда должны его писать)

Надеюсь, это поможет.

2 голосов
/ 13 августа 2011

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

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

См. MSDN: Проектирование структуры

Во-первых, ваша структура изменчива. Неизменяемые структуры не всегда являются лучшим решением 1015 *, но их следует учитывать ... см. Статью о том, как Microsoft использует структуры внутри класса Dictionary . Тем не менее, я бы определил основное требование: Требует ли структура изменчивости? Другими словами, изменится ли имя студента, номер единицы или отметка после создания экземпляра структуры?

Во-вторых, если требуется иметь коллекцию 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++;
}

Рассмотреть требования к структуре и дизайну надлежащим образом.

1 голос
/ 13 августа 2011

Вам необходимо правильно распечатать элементы структуры.Я хотел бы предложить метод, который выполняет печать для вас, учитывая структуру, такую ​​как

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

В качестве альтернативы создайте класс (это C #) и переопределите метод ToString () для возврата строки со всей информацией об элементеи вам не нужно будет модифицировать ваш основной код.

В C # все права использовать структуры, но в тех случаях, когда вам нужно представление данных, а не простая передача данных, чем вы должны использовать класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...