返回空数组而不是null

19

我创建了一个Settings类,用它来通过.ini文件编辑我的应用程序。我的Settings.ini文件如下:

[ACCOUNT]
login=xyz
password=xyz
locations=1,2,5,8

现在我是这样获取这些值的:

class Settings {
    public static IniFile Config = new IniFile(Directory.GetCurrentDirectory() + @"\Settings.ini");
    public static string Login { get { return Config.Read("login", "ACCOUNT"); } set { Config.Write("login", "ACCOUNT"); } }
    public static string Password { get { return Config.Read("password", "ACCOUNT"); } set { Config.Write("password", "ACCOUNT"); } }
    public static int[] Locations { get { return Array.ConvertAll(Config.Read("locations", "ACCOUNT").Split(','), s => int.Parse(s)); } set { Config.Write("locations", "ACCOUNT"); } }
}

问题是,当我的Settings.ini文件中有空位置时:

locations=

我的变量Settings.Locations返回null而不是一个空数组。我尝试做了这样的事情:

public static int[] Locations 
{ 
    get { return new int[] {Array.ConvertAll(Config.Read("locations", "ACCOUNT").Split(','), s => int.Parse(s))}; } 
    set { Config.Write("locations", "ACCOUNT"); } 
}

但那行不通。我无法将 int[] 转换为 int。您有什么想法如何返回空数组吗?


我不明白,如果没有位置,Config.Read("locations", "ACCOUNT") 会返回 null 吗?因为你的 Locations 属性从不返回 null,因为 Array.ConvertAll 从不返回 null。但是如果 Config.Read 返回 null,则 string.Split 会抛出异常。 - Tim Schmelter
你说得对。现在我注意到我正在收到“格式异常”。 - Brak Danych
你应该使用循环和 int.TryParse 来尝试解析每个标记,而不是使用 Array.ConvertAll。这样你就可以处理无效的输入了。 - Tim Schmelter
2个回答

23

你可以明确地这样做:

public static int[] Locations
{
    get
    {
        string locations = Config.Read("locations", "ACCOUNT");
        if (locations == null)
        {
            return new int[0];
        }
        return locations
                .Split(',')         // split the locations separated by a comma
                .Select(int.Parse)  // transform each string into the corresponding integer
                .ToArray();         // put the resulting sequence (IEnumerable<int>) into an array of integers
    }
    set
    {
        Config.Write("locations", "ACCOUNT");
    }
}

我不得不改成:if (string.IsNullOrEmpty(works)) {现在它运行良好。谢谢:) - Brak Danych
3
VS现在抱怨这个问题。它建议使用Array.Empty<int>(); - Mario Lopez

4

首先,您把太多的内容挤在一行中,这使得阅读和排查问题变得非常困难。您需要像这样:

对其进行改进:

public static int[] Locations 
{ 
    get 
    { 
        int[] values = Array.ConvertAll(Config.Read("locations", "ACCOUNT").Split(','), 
            s => int.Parse(s)) ?? new int[] { };
        return values; 
    } 
    set 
    { 
        Config.Write("locations", "ACCOUNT"); 
    } 
}

注意,我在第一个语句的结尾添加了“?? new int[] { }”,它被称为“空合并运算符”,如果另一个数组为null,则返回一个空数组。
这是一个偏好问题,但我将getter分成两行的原因是为了我可以在返回之前调试和中断以观察返回值。您也可以在最后一个括号上中断,然后在Locals窗口中观察返回值。

为什么要声明变量而不使用它们?除了漏写分号之外还有什么原因吗? - Camilo Terevinto
我一直收到“格式异常”错误,但我没有注意到它。你的代码也没有起作用。 - Brak Danych

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接