在控制离开当前方法

时间:2016-09-13 12:10:38

标签: c#

我是一个非常新的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 个答案:

答案 0 :(得分:5)

通过将参数声明为out,您承诺&#34;调用者(和编译器),您的方法将值设置为作为该参数的参数提供的变量。

因为您承诺,所以通过方法的每条路径都必须为此参数指定一个值。

您的方法tourists分配值。如果使用NullReferenceException引用调用该方法,这实际上可能导致tourists.Add(...) null

对我来说,似乎您可以在out中初始化tourists时忽略Main关键字。 注意 ReadData仅修改列表内容,而不是引用修改tourists变量中存储的内容。由于您不想更改该引用(变量的值),因此您不需要out关键字。

如果您希望ReadData初始化它,则需要添加行

tourists = new List<Tourist>()
<{1}} 之前 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

答案 1 :(得分:2)

需要在方法体中分配带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,该声明会将启动的值传递给方法,并提升要求以在该方法中指定它。

最后一个选项(就可读性而言,最好的一个IMO)是使列表成为返回值而不是out参数:

static void Main(string[] args)
{
    List<Tourist> tourists = ReadData();
}

static List<Tourist> ReadData()
{
    List<Tourist> tourists = new List<Tourist>();
    //...
    return tourists;
}

答案 2 :(得分:1)

在离开方法

之前,您必须为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