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