Параметр out должен быть назначен до того, как управление покинет текущие методы
Я очень новый C# , и это первый раз, когда я делаю что-то со списком, так что это может быть очень глупый вопрос... Я пытаюсь прочитать данные из файла в список, состоящий из объектов Tourist. Как я понимаю, мне нужно назначить что-то в список tourists, прежде чем добавлять в него объекты, но я не уверен, как это сделать.
class Tourist
{
public string FirstName { get; set; }
public string LastName { get; set; }
public double Contributed { get; set; }
public Tourist(string firstName, string lastName, double money)
{
FirstName = firstName;
LastName = lastName;
Contributed = money * 0.25;
}
}
class Program
{
static void Main(string[] args)
{
List<Tourist> tourists = new List<Tourist>();
ReadData(out tourists);
}
static void ReadData(out List<Tourist> tourists)
{
const string Input = "..\..\Duomenys.txt";
string[] lines = File.ReadAllLines(Input);
foreach (string line in lines)
{
string[] values = line.Split(';');
string firstName = values[0];
string lastName = values[1];
double money = Double.Parse(values[2]);
tourists.Add(new Tourist(firstName, lastName, money));
}
}
}
3 ответов:
Объявляя параметр как
out, вы "обещаете" вызывающему объекту (и компилятору), что ваш метод установит значение переменной, предоставленной в качестве аргумента для этого параметра.Поскольку вы это обещаете, каждый путь через ваш метод должен присваивать значение этому параметру.
Ваш метод не присваивает значение
tourists. Это может фактически привести кNullReferenceExceptionвtourists.Add(...), если метод вызывается со ссылкойnull.Мне это кажется, вы можете пропущены
outсайта, как вы инициализироватьtouristsужеMain. обратите внимание , чтоReadDataизменяет толькосодержимое списка , а нессылку на него, хранящуюся в переменнойtourists. Поскольку вы не хотите изменять эту ссылку (значение переменной ), вам не нужно ключевое словоout.Если вы хотите
ReadDataинициализировать его, вам нужно добавить строкуtourists = new List<Tourist>()В
ReadDataперед theforeachпетля.
Поскольку ваш код стоит, лучшим решением будет ommit любой параметр в
ReadDataи пусть метод возвращает список вместо этого:static List<Tourist> ReadData() { // create list List<Tourist> tourists = new List<Tourist>(); const string Input = "..\\..\\Duomenys.txt"; string[] lines = File.ReadAllLines(Input); foreach (string line in lines) { // shortened for brevity tourists.Add(new Tourist(firstName, lastName, money)); } return tourists; // return newly created list }И использовать это в
Mainкак:static void Main(string[] args) { List<Tourist> tourists = ReadData(); }
Параметры с
outдолжны быть назначены в теле метода и не переносить их значение с сайта вызова. Цитирование msdn:В методе, как и в локальной переменной, выходной параметр изначально считается неназначенным и должен быть определенно присвоен, прежде чем его значение будет использовано.
В вашем случае есть три способа решить эту проблему:
Во-первых, вы можете переместить назначение от вызывающего объекта к методу:
static void Main(string[] args) { List<Tourist> tourists; ReadData(out tourists); } static void ReadData(out List<Tourist> tourists) { tourists = new List<Tourist>(); //... }Второй, вы можете изменить свое объявление на пропуск
outв объявлении полностью, что перенесет инициированное значение в метод и отменит требование присвоить его в этом методе.Последний вариант (и лучший ИМО, с точки зрения читаемости) - сделать список возвращаемым значением вместо параметра
out:static void Main(string[] args) { List<Tourist> tourists = ReadData(); } static List<Tourist> ReadData() { List<Tourist> tourists = new List<Tourist>(); //... return tourists; }
Вы должны указать значение для вашего
out-параметра, прежде чем покинуть методstatic void ReadData(out List<Tourist> tourists) { const string Input = "..\\..\\Duomenys.txt"; tourists = new List<Tourist>(); string[] lines = File.ReadAllLines(Input); foreach (string line in lines) { string[] values = line.Split(';'); string firstName = values[0]; string lastName = values[1]; double money = Double.Parse(values[2]); tourists.Add(new Tourist(firstName, lastName, money)); } }Однако, поскольку вы передаете
List<T>, который является ссылочным типом, вам не нуженout.ключевое слово как модификация объекта, на который вы ссылаетесь, отражается в всех ссылках.Поэтому после вызова
ReadDataсписок, который вы предоставили, также изменится:var tourists = new List<Tourist>(); ReadData(toursists); // this changes the elements within the list // do something with the list
Comments