out参数必须在控件离开当前方法之前赋值
本文关键字:方法 赋值 离开 控件 参数 out | 更新日期: 2023-09-27 18:06:52
我是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));
}
}
}
通过将参数声明为out
,您向调用者(和编译器)"承诺"您的方法将为该参数提供的变量设置值。
因为你答应了,所以通过方法的每个路径都必须给这个参数赋值。
您的方法不分配值给tourists
。这实际上可能导致NullReferenceException
在tourists.Add(...)
如果方法被调用的null
引用。
对我来说,似乎你可以在Main
中初始化tourists
时提交out
关键字。注意 ReadData
只修改列表的内容,而不是存储在tourists
变量中的引用。由于您不想更改该引用(变量的值),因此不需要out
关键字。
如果您希望ReadData
初始化它,您需要添加
tourists = new List<Tourist>()
在ReadData
foreach
循环之前
根据您的代码,更好的解决方案是将任何参数提交给
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