如何在 C# 中初始化空数组

本文关键字:初始化 数组 | 更新日期: 2023-09-27 18:19:29

是否可以在不指定大小的情况下创建一个空数组?

例如,我创建了:

String[] a = new String[5];

我们可以在没有大小的情况下创建上面的字符串数组吗?

如何在 C# 中初始化空数组

如果你打算使用一个你事先不知道大小的集合,有比数组更好的选择。

改用List<string> - 它将允许您根据需要添加任意数量的项目,如果您需要返回数组,请对变量调用ToArray()

var listOfStrings = new List<string>();
// do stuff...
string[] arrayOfStrings = listOfStrings.ToArray();

如果必须创建一个空数组,则可以执行以下操作:

string[] emptyStringArray = new string[0]; 

在 .NET 4.6 中,首选方法是使用新方法,Array.Empty

String[] a = Array.Empty<string>();

该实现简洁,使用泛型类中的静态成员在 .Net 中的行为方式:

public static T[] Empty<T>()
{
    return EmptyArray<T>.Value;
}
// Useful in number of places that return an empty byte array to avoid
// unnecessary memory allocation.
internal static class EmptyArray<T>
{
    public static readonly T[] Value = new T[0];
}

(为清楚起见,删除了与代码协定相关的代码(

另请参阅:

  • Array.Empty引用源上的源代码
  • Array.Empty<T>()简介
  • Marc Gravell - 分配,分配,分配 - 我最喜欢的关于微小隐藏分配的文章。

试试这个:

string[] a = new string[] { };

您可以使用大小为 0 来初始化它,但是当您知道大小时,您必须重新初始化它,因为您无法附加到数组中。

string[] a = new string[0];

声明一个没有大小的数组没有多大意义。数组与大小有关。声明特定大小的数组时,指定集合中可以容纳内容的固定可用插槽数,并相应地分配内存。要向其添加一些内容,无论如何都需要重新初始化现有数组(即使您正在调整数组的大小,请参阅此线程(。想要初始化空数组的罕见情况之一是将数组作为参数传递。

如果你想定义一个集合,而你不知道它可能是什么大小,数组不是你的选择,而是像List<T>或类似的东西。

也就是说,在不指定大小的情况下声明数组的唯一方法是拥有一个大小为 0 的空数组。hemant和Alex Dn提供了两种方式。另一个更简单的替代方案是:

string[] a = { };

[括号内的元素应隐式转换为定义的类型,例如string[] a = { "a", "b" };

或者另一个:

var a = Enumerable.Empty<string>().ToArray();

下面是一个更具声明性的方法

public static class Array<T>
{
    public static T[] Empty()
    {
        return Empty(0);
    }
    public static T[] Empty(int size)
    {
        return new T[size];
    }
}

现在您可以致电:

var a = Array<string>.Empty();
//or
var a = Array<string>.Empty(5);

string[] a = new string[0];

或简短符号:

string[] a = { };

现在的首选方法是:

var a = Array.Empty<string>();

我写了一个简短的正则表达式,如果你想替换零长度分配,你可以在Visual Studio中使用,例如 new string[0] .在打开正则表达式选项的情况下,在 Visual Studio 中使用查找(搜索(:

new[ ][a-zA-Z0-9]+'[0']

现在查找全部或 F3(查找下一个(并将所有替换为 Array.Empty<...>(( !

简单而优雅!

string[] array = {}

性能规则 CA1825:避免分配零长度数组。

规则描述:初始化零长度数组会导致不必要的内存分配。相反,请通过调用 Array.Empty 方法来使用静态分配的空数组实例。

在您的情况下:

var a = Array.Empty<string>(); 

您可以在运行时定义数组大小

这将允许您执行任何操作来动态计算数组的大小。但是,一旦定义,大小是不可变的。

Array a = Array.CreateInstance(typeof(string), 5);

我试过:

string[] sample = new string[0];

但是我只能在其中插入一个字符串,然后我得到了一个异常OutOfBound错误,所以我只是简单地为它输入一个大小,例如

string[] sample = new string[100];

或者另一种对我有用的方式:

List<string> sample = new List<string>();

为列表分配值:

sample.Add(your input);

据我所知,没有大小就无法制作数组,但您可以使用

List<string> l = new List<string>() 

然后l.ToArray().

结合@nawfal和@Kobi建议:

namespace Extensions
{
    /// <summary> Useful in number of places that return an empty byte array to avoid unnecessary memory allocation. </summary>
    public static class Array<T>
    {
        public static readonly T[] Empty = new T[0];
    }
}

使用示例:

Array<string>.Empty

更新 2019-05-14

(致谢@Jaider TY(

更好地使用 .Net API:

public static T[] Empty<T> ();

https://learn.microsoft.com/en-us/dotnet/api/system.array.empty?view=netframework-4.8

适用于:

.NET 核心:3.0 预览版 5

2.2 2.1 2.0 1.1 1.0

.NET 框架: 4.8 4.7.2 4.7.1 4.7 4.6.2 4.6.1 4.6

.NET 标准版:2.1 预览版 2.0 1.6 1.5 1.4 1.3

您可以使用

Array.Empty方法(至少在.Net Core中(

string ToCsv(int[] myArr = null) { // null by default
    // affect an empty array if the myArr is null
    myArr ??= Array.Empty<int>();
    
    //... do stuff
    string csv = string.Join(",", myArr);
    return csv;
}

这是一个真实世界的例子。在这种情况下,有必要将数组初始化foundFiles首先为零长度。

(正如其他答案中所强调的:这初始化的不是元素,尤其是索引为零的元素,因为这意味着数组的长度为 1。数组在此行之后的长度为零!

如果省略部分= string[0],则存在编译器错误!

这是因为没有重新抛出的捕获块。C# 编译器识别代码路径,该函数Directory.GetFiles()可以引发异常,以便数组可以取消初始化。

在任何人说之前,不重新抛出异常将是糟糕的错误处理:这不是真的。错误处理必须符合要求。

在这种情况下,假设程序应该在目录无法读取的情况下继续,而不是中断 - 最好的例子是遍历目录结构的函数。这里的错误处理只是记录它。当然,这可以做得更好,例如,将GetFiles(Dir)调用失败的所有目录收集到列表中,但这会导致太远。

只要声明避免throw是一个有效的方案就足够了,因此必须将数组初始化为长度为零。在 catch 块中执行此操作就足够了,但这将是糟糕的风格。

GetFiles(Dir) 的调用会调整数组的大小。

string[] foundFiles= new string[0];
string dir = @"c:'";
try
{
    foundFiles = Directory.GetFiles(dir);  // Remark; Array is resized from length zero
}
// Please add appropriate Exception handling yourself
catch (IOException)
{
  Console.WriteLine("Log: Warning! IOException while reading directory: " + dir);
  // throw; // This would throw Exception to caller and avoid compiler error
}
foreach (string filename in foundFiles)
    Console.WriteLine("Filename: " + filename);

你可以做:

string[] a = { String.Empty };

注意:OP 意味着不必指定大小,而不是使数组无大小

好像string[] a = {};和上述内容就它们的差异而言真的很重要!执行任一操作的重点只是在(重新(填充数组之前实例化或清除数组。