简体   繁体   English

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

[英]How do I initialize an empty array in C#?

Is it possible to create an empty array without specifying the size?是否可以在不指定大小的情况下创建一个空数组?

For example, I created:例如,我创建了:

String[] a = new String[5];

Can we create the above string array without the size?我们可以创建上面没有大小的字符串数组吗?

If you are going to use a collection that you don't know the size of in advance, there are better options than arrays.如果您要使用事先不知道大小的集合,则有比数组更好的选择。

Use a List<string> instead - it will allow you to add as many items as you need and if you need to return an array, call ToArray() on the variable.改用List<string> - 它将允许您根据需要添加任意数量的项目,如果您需要返回一个数组,请在变量上调用ToArray()

var listOfStrings = new List<string>();

// do stuff...

string[] arrayOfStrings = listOfStrings.ToArray();

If you must create an empty array you can do this:如果您必须创建一个空数组,您可以这样做:

string[] emptyStringArray = new string[0]; 

试试这个:

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

In .NET 4.6 the preferred way is to use a new method, Array.Empty :在 .NET 4.6 中,首选方法是使用新方法Array.Empty

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

The implementation is succinct, using how static members in generic classes behave in .Net : 实现是简洁的,使用泛型类中的静态成员在 .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];
}

(code contract related code removed for clarity) (为清晰起见,代码合同相关代码已删除)

See also:也可以看看:

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

string[] a = new string[0];

There is not much point in declaring an array without size.声明一个没有大小的数组没有多大意义。 An array is about size .一个数组大约是 size When you declare an array of specific size, you specify the fixed number of slots available in a collection that can hold things, and accordingly memory is allocated.当您声明一个特定大小的数组时,您指定了集合中可以容纳事物的固定可用槽数,并相应地分配内存。 To add something to it, you will need to anyway reinitialize the existing array (even if you're resizing the array, see this thread ).要向其中添加内容,您无论如何都需要重新初始化现有数组(即使您正在调整数组大小, 请参阅此线程)。 One of the rare cases where you would want to initialise an empty array would be to pass array as an argument.您想要初始化空数组的罕见情况之一是将数组作为参数传递。

If you want to define a collection when you do not know what size it could be of possibly, array is not your choice, but something like a List<T> or similar.如果您想在不知道集合可能有多大的情况下定义集合,则数组不是您的选择,而是类似于List<T>或类似的东西。

That said, the only way to declare an array without specifying size is to have an empty array of size 0 .也就是说,在不指定大小的情况下声明数组的唯一方法是拥有一个大小为 0的空数组。 hemant and Alex Dn provides two ways. hemantAlex Dn提供了两种方式。 Another simpler alternative is to just :另一个更简单的选择是

string[] a = { };

[ The elements inside the bracket should be implicitly convertible to type defined, for instance, string[] a = { "a", "b" }; [括号内的元素应该可以隐式转换为类型定义,例如, string[] a = { "a", "b" }; ] ]

Or yet another:或者另一个:

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

Here is a more declarative way :这是一种更具声明性的方式

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

    public static T[] Empty(int size)
    {
        return new T[size];
    }
}

Now you can call:现在你可以调用:

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

//or

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

简单而优雅!

string[] array = {}

string[] a = new string[0];

or short notation:或简写:

string[] a = { };

The preferred way now is:现在首选的方式是:

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

I have written a short regular expression that you can use in Visual Studio if you want to replace zero-length allocations eg new string[0] .我编写了一个简短的正则表达式,如果您想替换零长度分配(例如new string[0] ,您可以在 Visual Studio 中使用它。 Use Find (search) in Visual Studio with Regular Expression option turned on:在打开正则表达式选项的情况下在 Visual Studio 中使用查找(搜索):

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

Now Find All or F3 (Find Next) and replace all with Array.Empty<…>() !现在 Find All 或 F3 (Find Next) 并用 Array.Empty<…>() 替换 all !

You can define array size at runtime .您可以在运行时定义数组大小

This will allow you to do whatever to dynamically compute the array's size.这将允许您执行任何动态计算数组大小的操作。 But, once defined the size is immutable.但是,一旦定义大小是不可变的。

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

I had tried:我试过:

string[] sample = new string[0];

But I could only insert one string into it, and then I got an exceptionOutOfBound error, so I just simply put a size for it, like但是我只能在其中插入一个字符串,然后我得到了一个 exceptionOutOfBound 错误,所以我只是简单地为它设置了一个大小,比如

string[] sample = new string[100];

Or another way that work for me:或者另一种对我有用的方法:

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

Assigning Value for list:为列表赋值:

sample.Add(your input);

Combining @nawfal & @Kobi suggestions:结合@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];
    }
}

Usage example:用法示例:

Array<string>.Empty

UPDATE 2019-05-14更新 2019-05-14

(credits to @Jaider ty) (归功于@Jaider ty)

Better use .Net API:更好地使用 .Net API:

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

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

Applies to:适用于:

.NET Core: 3.0 Preview 5 2.2 2.1 2.0 1.1 1.0 .NET Core:3.0 预览版 5 2.2 2.1 2.0 1.1 1.0

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

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

... ...

HTH HTH

As I know you can't make array without size, but you can use据我所知,您不能在没有大小的情况下创建数组,但是您可以使用

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

and then l.ToArray() .然后是l.ToArray()

You can do:你可以做:

string[] a = { String.Empty };

Note: OP meant not having to specify a size, not make an array sizeless注意:OP 意味着不必指定大小,而不是使数组无大小

Here is a real world example.这是一个真实世界的例子。 In this it is necessary to initialize the array foundFiles first to zero length.在这种情况下,必须首先将数组foundFiles初始化为零长度。

(As emphasized in other answers: This initializes not an element and especially not an element with index zero because that would mean the array had length 1. The array has zero length after this line!). (正如在其他答案中所强调的:这不是一个元素,尤其不是一个索引为零的元素,因为这意味着数组的长度为 1。该数组在此行之后的长度为零!)。

If the part = string[0] is omitted, there is a compiler error!如果省略 part = string[0] ,则编译器出错!

This is because of the catch block without rethrow.这是因为 catch 块没有重新抛出。 The C# compiler recognizes the code path, that the function Directory.GetFiles() can throw an Exception, so that the array could be uninitialized. C# 编译器识别代码路径,函数Directory.GetFiles()可以抛出异常,因此可以未初始化数组。

Before anyone says, not rethrowing the exception would be bad error handling: This is not true.在任何人说之前,不重新抛出异常将是糟糕的错误处理:这不是真的。 Error handling has to fit the requirements.错误处理必须符合要求。

In this case it is assumed that the program should continue in case of a directory which cannot be read, and not break- the best example is a function traversing through a directory structure.在这种情况下,假设程序应该在无法读取的目录的情况下继续运行,而不是中断 - 最好的例子是遍历目录结构的函数。 Here the error handling is just logging it.这里的错误处理只是记录它。 Of course this could be done better, eg collecting all directories with failed GetFiles(Dir) calls in a list, but this will lead too far here.当然,这可以做得更好,例如将所有具有失败GetFiles(Dir)调用的目录收集到一个列表中,但这在这里会走得太远。

It is enough to state that avoiding throw is a valid scenario, and so the array has to be initialized to length zero.声明避免throw是一个有效的场景就足够了,因此必须将数组初始化为长度为零。 It would be enough to do this in the catch block, but this would be bad style.在 catch 块中这样做就足够了,但这将是糟糕的风格。

The call to GetFiles(Dir) resizes the array.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);

you can use the Array.Empty method (in .Net Core, at least)您可以使用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;
}

Performance Rule CA1825: Avoid allocating zero-length arrays.性能规则 CA1825:避免分配零长度 arrays。

Rule discription: Initializing a zero-length array leads to an unnecessary memory allocation.规则说明:初始化零长度数组会导致不必要的 memory 分配。 Instead, use the statically allocated empty array instance by calling the Array.Empty method.相反,通过调用 Array.Empty 方法使用静态分配的空数组实例。

In your case:在你的情况下:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM