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

Posted

技术标签:

【中文标题】如何在 C# 中初始化一个空数组?【英文标题】:How do I initialize an empty array in C#? 【发布时间】:2012-02-02 08:54:12 【问题描述】:

是否可以创建一个空数组而不指定大小?

例如,我创建了:

String[] a = new String[5];

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

【问题讨论】:

***.com/questions/151936/…你检查这个链接,它可以帮助你清楚地理解数组的东西 另见all-possible-c-sharp-array-initialization-syntaxes 【参考方案1】:

如果您要使用事先不知道大小的集合,则有比数组更好的选择。

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

var listOfStrings = new List<string>();

// do stuff...

string[] arrayOfStrings = listOfStrings.ToArray();

如果您必须创建一个空数组,您可以这样做:

string[] emptyStringArray = new string[0]; 

【讨论】:

@Oded -- string[] emptyStringArray = new string[0];不会导致空数组,是吗?看起来它是一个包含一个元素的数组,其中该元素为空。 @roryap - 不。它会产生一个没有元素的string[]。如果你尝试访问emptyStringArray[0],你会得到一个IndexOutOfRangeException @Oded -- 谢谢,我对 C# 还很陌生。在 VB 中,提供的索引是上限,而不是元素的数量。 你认为哪个更好:var strings = new string[];或 var strings = new string[0];顺便说一句:我认为空数组是方法参数的完全有效默认值: public void EditItems(IEnumerable toEdit, IEnumerable toDelete = new long[]) @RickO'Shea - C++ 不是 C#。 Stroustrup 了解他的 C++ - 不太确定他是否了解他的 C# 和 .NET GC。不会和你发生宗教战争。【参考方案2】:

试试这个:

string[] a = new string[]  ;

【讨论】:

扩展此答案,您还可以使用项目初始化数组而不指定大小或类型,编译器将从初始化程序推断: var a = new []"a", "b “, “C”;这仍然是一个强类型字符串数组。 未处理的异常:System.IndexOutOfRangeException:索引超出了数组的边界。在 ArrayClass.Main(String[] args)。我更改了 int[] variable = new int[] 后遇到了这个错误 @yogesh:这很奇怪。例如,当编写int[] variable = new int[] 并在诸如foreach (var s in variable) Console.WriteLine(s); 之类的循环中使用它时,代码将编译为:int[] args1 = new int[0];foreach (int num in args1)Console.WriteLine(num);。所以使用new int[0]new int[] 应该没有区别,因为它们都被编译成相同的代码。 @GlennGordon 绝对是,但这是 C# 3.0 版(从 2007 年开始,使用 Visual Studio 2008)的新功能。该版本还允许使用 var 的另一种简单格式,尽管仅适用于局部变量(不适用于字段)。但是在 C# 2.0 (Visual Studio 2005) 和更早版本中,您必须使用此答案的语法(或 string[] a = new string[0];)。【参考方案3】:

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

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

implementation 简洁,使用how static members in generic classes behave in .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 source code on Reference Source Introduction to Array.Empty&lt;T&gt;() Marc Gravell - Allocaction, Allocation, Allocation - 我最喜欢的关于微小隐藏分配的帖子。

【讨论】:

绝对是对可读性的改进:Enumerable.Empty&lt;T&gt;().ToArray() 尽管这种方法在大多数情况下绝对是首选,但它并不能回答最初的问题。 OP 想要创建 一个空数组。 Array.Empty&lt;T&gt;() 创建一个数组。它返回对预分配数组的引用。 为什么EmptyArray&lt;T&gt; 是一个单独的类,而不是让它成为Array&lt;T&gt; 的一部分?【参考方案4】:

你可以用 0 的大小初始化它,但是当你知道它的大小时,你必须重新初始化它,因为你不能追加到数组中。

string[] a = new string[0];

【讨论】:

这是准确的答案【参考方案5】:

声明一个没有大小的数组没有多大意义。数组大小差不多。当你声明一个特定大小的数组时,你指定了一个集合中可以容纳东西的固定数量的可用槽,并相应地分配内存。要添加一些东西,无论如何您都需要重新初始化现有数组(即使您正在调整数组大小,see this thread)。您想要初始化一个空数组的罕见情况之一是将数组作为参数传递。

如果您想在不知道它可能有多大大小的情况下定义一个集合,则数组不是您的选择,而是List&lt;T&gt; 或类似的东西。

也就是说,声明数组而不指定大小的唯一方法是使用 大小为 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);

【讨论】:

我想不出任何用处,除非您必须将数组作为参数传递。在反射中有几种情况,其中方法接受对象数组,您可能希望传递一个空数组以实现默认操作。我将编辑我的答案。 例如,您有一个由多个返回 IEnumerable 的类实现的接口,其中一个实现没有该方法的元素并返回一个空数组。 @IgnaciosolerGarcia 在这种情况下,当且仅当它是一个性能极其关键的应用程序时,我才会返回一个数组。我会说数组已经过时,如果可以的话应该避免使用。见this by Lippert 和this S.O. question 请记住,返回的类型是 IEnumerable,因此该数组是只读的并且不打算更改。例如,在这种情况下,我为什么要返回一个列表? 一个空数组的用例很简单——当你想用对象填充它但你不知道要添加多少!【参考方案6】:

简洁优雅!

string[] array = 

【讨论】:

我会将array 更改为a,因为array 是大写的关键字。将关键字名称用作变量名称只是不好的做法 - 即使大小写不同。基本上和我的回答一样,除了我在里面有String.Empty 1. array 不是 c# 关键字。数组是一个类而不是关键字 2.“a”也是不好的做法(可能比使用关键字更糟糕) 技术。类,关键字,它定义了一个对象类型,仍然不好。为什么你认为a 不好? 因为非描述性和单字母变量名是不好的做法,因为它们没有传达定义它们的原因。 “array”当然是比“a”更好的名字。一个更好的名字是“emptyArray”。【参考方案7】:

string[] a = new string[0];

或简称:

string[] a = ;

现在首选的方式是:

var a = Array.Empty&lt;string&gt;();

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

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

现在 Find All 或 F3(查找下一个)并将所有替换为 Array.Empty() !

【讨论】:

【参考方案8】:

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

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

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

【讨论】:

为什么要这么做?在运行时,您通常可以从变量中定义数组大小:int i = 5; string[] a = new string[i]; 好吧,我猜对于泛型这似乎已经过时了。【参考方案9】:

我试过了:

string[] sample = new string[0];

但我只能在其中插入一个字符串,然后我得到一个 exceptionOutOfBound 错误,所以我只是简单地为其设置一个大小,比如

string[] sample = new string[100];

或者其他适合我的方式:

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

为列表赋值:

sample.Add(your input);

【讨论】:

【参考方案10】:

据我所知,你不能制作没有大小的数组,但你可以使用

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

然后是l.ToArray()

【讨论】:

【参考方案11】:

结合@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://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=netframework-4.8

适用于:

.NET Core: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 Standard:2.1 预览版 2.0 1.6 1.5 1.4 1.3

...

HTH

【讨论】:

在 .NET Core 2 中,已经有一个扩展,arr = Array.Empty&lt;string&gt;(); iirc,在 .NetStandart [4.something] - 还有。【参考方案12】:

您可以使用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;

【讨论】:

【参考方案13】:

你可以这样做:

string[] a =  String.Empty ;

注意:OP 意味着不必指定大小,而不是创建数组 sizeless

【讨论】:

这不会创建一个长度为 1 的字符串数组吗? 是的,但已清除。并且 OP 要求声明数组而不必说明大小 - 这很适合。 这值得一票否决,为什么? OP 意味着不必specify 一个大小,不必创建一个数组sizeless @vapcguy 我是反对者。我后悔了。我已编辑您的答案以取消我的反对票。你的评论使这个问题有点可疑。不确定这是否是 OP 的意思。 OP 要求一个 empty 数组。该数组不为空。【参考方案14】:

这是一个真实的例子。在此需要先将数组foundFiles 初始化为零长度。

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

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

这是因为没有重新抛出的 catch 块。 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);

【讨论】:

以上是关于如何在 C# 中初始化一个空数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UITableView 中安全地使用未初始化的数组并显示一个空表

数组语义初始化器如何在 C# 中工作?

如何在 React 初始状态下使用空数组声明?

如何在 C# 中为 Matrix 类初始化二维数组

如何在简洁的单行初始化语句中用 n 个不同的空数组填充新数组? [复制]

如何在 C# 模型类中设置数组属性的值