C# 向 T 类型的类数组添加扩展 Append 方法

use*_*579 1 c# arrays generics extension-methods append

使用这个问题的答案如何将字符串添加到 string[] 数组?没有 .Add 函数”我试图使用这个答案来编写一个通用扩展以将元素附加到 .Add 函数generic array。仅使用该Array.Resize()方法效果很好,下面的示例向我的string array

string[] array = new string[] { "Foo", "Bar" };
Array.Resize(ref array, array.Length + 1);
array[array.Length - 1] = "Baz";
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用下面描述的 ArrayExtension 方法时,该方法确实在方法内调整了数组的大小,但是当它返回时数组没有改变?

我的扩展课

public static class ArrayExtensions
{
    public static void Append<T>(this T[] array, T append)
    {
        Array.Resize(ref array, array.Length + 1);
        array[array.Length - 1] = append;    // < Adds an extra element to my array
    }
}
Run Code Online (Sandbox Code Playgroud)

使用如下

string[] array = new string[] { "Foo", "Bar" };
array.Append("Baz");
Run Code Online (Sandbox Code Playgroud)

当该方法返回时,添加的元素不存在。我缺少什么?

更新

正如所指出的,这个问题之前已经在这里被提出和回答过。我将接受上一个问题“在扩展方法中更改数组大小不起作用? ”作为我的问题的答案。

更新2

由于如果在扩展方法中使用返回方法,它确实违反了框架中 Append() 修改对象本身的类似类的预期行为,因此我对扩展方法做了一些更改以防止它被错误使用。感谢@NineBerry 指出了这一点。

我还添加了params T[] add允许一次添加多个元素的功能。

public static class ArrayExtensions
{
    /// <summary>
    /// Creates a copy of an object array and adds the extra elements to the created copy
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="array"></param>
    /// <param name="add">Elemet to add to the created copy</param>
    /// <returns></returns>
    public static T[] CopyAddElements<T>(this T[] array, params T[] add)
    {
        for (int i = 0; i < add.Length; i++)
        {
            Array.Resize(ref array, array.Length + 1);
            array[array.Length - 1] = add[i];
        }
        return array;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

string[] array = new string[] { "Foo", "Bar" };
array = array.CopyAddElements("Baz", "Foobar");
for (int i = 0; i < array.Length; i++)
{
    System.Console.Write($"{array[i]} ");
}

/* Output
 *  Foo Bar Baz Foobar
*/
Run Code Online (Sandbox Code Playgroud)

Nin*_*rry 5

Array.Resize创建一个新数组。ref这就是为什么您必须使用关键字 to传递数组Array.Resize。因此,从 返回后Array.Resize,该变量array引用了另一个对象。

无法使用扩展方法来完成您想要做的事情。

为什么不简单地使用 List<> 而不是数组呢?使用Array.Resize是一个非常昂贵的操作。这意味着每次调用它以增加数组长度时,都会分配新的内存并将数据从旧数组复制到新数组。