在扩展方法中更改数组的大小不起作用? [英] Changing size of array in extension method does not work?

查看:161
本文介绍了在扩展方法中更改数组的大小不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以基本上我写了我的数组类型的Add扩展方法.

So basically I wrote my little Add extension method for array types.

using System;
using System.Linq;
public static class Extensions 
{
    public static void Add<T>(this T[] _self, T item)
    {
        _self = _self.Concat(new T[] { item }).ToArray();
    }
}
public class Program
{
    public static void Main()
    {
        string[] test = { "Hello" };
        test = test.Concat(new string[] { "cruel" }).ToArray();
        test.Add("but funny");
        Console.WriteLine(String.Join(" ", test) + " world");
    }
}

输出应为Hello cruel but funny world,但but funny永远不会在扩展方法内串联.

The output should be Hello cruel but funny world, but the but funny will never be concatenated within the extension method.

编辑扩展中的相同数组似乎也不起作用:

Editing the same array in the extension seems not to work, too:

using System;
using System.Linq;
public static class Extensions 
{
    public static void Add<T>(this T[] _self, T item)
    {
        Array.Resize(ref _self, _self.Length + 1);
        _self[_self.Length - 1] = item;
    }
}
public class Program
{
    public static void Main()
    {
        string[] test = { "Hello" };
        test = test.Concat(new string[] { "cruel" }).ToArray();
        test.Add("but funny");
        Console.WriteLine(String.Join(" ", test) + " world");
    }
}

我在这里弄错了什么,如何使用它作为扩展名?

What did I get wrong here, how can I use it as extension?

.dotNet小提琴: https://dotnetfiddle.net/9os8nY

.dotNet fiddle: https://dotnetfiddle.net/9os8nY or https://dotnetfiddle.net/oLfwRD

(很高兴找到一种方法,这样我就可以保持通话test.Add("item");)

(It would be great to find a way so I can keep the call test.Add("item");)

推荐答案

您正在为参数分配一个新引用,除非您将其作为ref参数传递,否则它不会更改实际数组.由于这是一种扩展方法,因此不是一种选择.因此,请考虑使用常规方法:

You are assigning a new reference to the argument,it won't change the actual array unless you pass it as ref parameter. Since this is an extension method it's not an option. So consider using a normal method:

public static void Add<T>(ref T[] _self, T item)
{
    _self = _self.Concat(new T[] { item }).ToArray();
}

Add(ref test, "but funny");

或者,如果您坚持使用扩展方法,则需要使数组成为第二个参数才能使用ref:

Or if you insist on using extension methods you need to make the array second parameter in order to use ref:

public static void AddTo<T>(this T item, ref T[] arr, )
{
    arr = arr.Concat(new T[] { item }).ToArray();
}

"but funny".AddTo(ref test);

Array.Resize不起作用.因为它更改了_self而不是test数组.现在,当您传递不带ref关键字的引用类型时,该引用将被复制.就像这样:

Array.Resize doesn't work. Because it changes the _self, not the test array. Now when you pass a reference type without ref keyword, the reference is copied. It's something like this:

string[] arr1 = { "Hello" };
string[] arr2 = arr1;

现在,如果您为arr2分配新的引用,它将不会更改arr1的引用.Array.Resize所做的是,由于无法调整数组的大小,它将创建一个新的数组并进行复制将所有元素都分配到新数组中,并将该新引用分配给参数(在本例中为_self).因此,它将更改_self指向的位置,但由于_selftest是两个不同的引用(例如arr1arr2),更改其中一个不会影响另一个.

Now, if you assign a new reference to arr2, it will not change arr1's reference.What Array.Resize is doing is that since resizing an array is not possible, it creates a new array and copies all elements to a new array and it assigns that new reference to the parameter (_self in this case).So it changes the where _self points to but since _self and test are two different references (like arr1 and arr2), changing one of them doesn't affect the other.

另一方面,如果像我的第一个示例一样将数组作为ref传递给方法,则Array.Resize也会按预期工作,因为在这种情况下,不会复制引用:

On the other hand if you pass array as ref to your method as in my first example, the Array.Resize will also work as expected, because in this case the reference will not be copied:

public static void Add<T>(ref T[] _self, T item)
{
    Array.Resize(ref _self, _self.Length + 1);
    _self[_self.Length - 1] = item;
}

这篇关于在扩展方法中更改数组的大小不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆