在扩展方法中更改数组大小不起作用?
Changing size of array in extension method does not work?
所以基本上我为数组类型编写了我的 Add
扩展方法。
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
永远不会在扩展方法中连接起来。
在扩展中编辑同一个数组似乎也不起作用:
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");
}
}
我哪里搞错了,我怎样才能将它用作扩展?
.dotNet 小提琴:https://dotnetfiddle.net/9os8nY or https://dotnetfiddle.net/oLfwRD
(如果能找到一种方法让我可以继续通话就好了test.Add("item");
)
您正在为参数分配一个新引用,它不会更改实际数组,除非您将其作为 ref
参数传递。由于这是一种扩展方法,因此它不是一种选择。所以考虑使用普通方法:
public static void Add<T>(ref T[] _self, T item)
{
_self = _self.Concat(new T[] { item }).ToArray();
}
Add(ref test, "but funny");
或者,如果您坚持使用扩展方法,则需要将数组作为第二个参数才能使用 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
关键字的引用类型时,将复制该引用。是这样的:
string[] arr1 = { "Hello" };
string[] arr2 = arr1;
现在,如果您为 arr2
分配一个新的引用,它不会改变 arr1
的 reference.What Array.Resize
正在做的是因为调整数组的大小是不可能,它会创建一个新数组并将所有元素复制到一个新数组,并将该新引用分配给 参数 (在本例中为 _self
)。因此它更改了_self
指向但由于 _self
和 test
是两个不同的引用(如 arr1
和 arr2
),更改其中一个不会影响另一个.
另一方面,如果像我的第一个示例那样将数组作为 ref
传递给方法,Array.Resize
也将按预期工作,因为在这种情况下不会复制引用:
public static void Add<T>(ref T[] _self, T item)
{
Array.Resize(ref _self, _self.Length + 1);
_self[_self.Length - 1] = item;
}
我相信 _self =
将 _self
对象的副本创建到为参数 _self
创建的局部变量中 - 因此不会更新原始对象。使用像列表这样的引用类型,或者创建一个 returns 新数组的静态方法。
根据 'feel' 的原因:您在变量实例上调用方法 - 您不能从在它的上下文下执行的代码中更改该实例
您可以这样更改代码:
public static class Extensions
{
public static T[] Add<T>(this T[] _self, T item)
{
return _self.Concat(new T[] { item }).ToArray();
}
}
public class Program
{
public static void Main()
{
string[] test = { "Hello" };
test = test.Concat(new string[] { "cruel" }).ToArray();
test = test.Add("but funny");
Console.WriteLine(String.Join(" ", test) + " world");
}
}
附带说明 - 用法与 Concat 方法相同。
所以基本上我为数组类型编写了我的 Add
扩展方法。
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
永远不会在扩展方法中连接起来。
在扩展中编辑同一个数组似乎也不起作用:
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");
}
}
我哪里搞错了,我怎样才能将它用作扩展?
.dotNet 小提琴:https://dotnetfiddle.net/9os8nY or https://dotnetfiddle.net/oLfwRD
(如果能找到一种方法让我可以继续通话就好了test.Add("item");
)
您正在为参数分配一个新引用,它不会更改实际数组,除非您将其作为 ref
参数传递。由于这是一种扩展方法,因此它不是一种选择。所以考虑使用普通方法:
public static void Add<T>(ref T[] _self, T item)
{
_self = _self.Concat(new T[] { item }).ToArray();
}
Add(ref test, "but funny");
或者,如果您坚持使用扩展方法,则需要将数组作为第二个参数才能使用 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
关键字的引用类型时,将复制该引用。是这样的:
string[] arr1 = { "Hello" };
string[] arr2 = arr1;
现在,如果您为 arr2
分配一个新的引用,它不会改变 arr1
的 reference.What Array.Resize
正在做的是因为调整数组的大小是不可能,它会创建一个新数组并将所有元素复制到一个新数组,并将该新引用分配给 参数 (在本例中为 _self
)。因此它更改了_self
指向但由于 _self
和 test
是两个不同的引用(如 arr1
和 arr2
),更改其中一个不会影响另一个.
另一方面,如果像我的第一个示例那样将数组作为 ref
传递给方法,Array.Resize
也将按预期工作,因为在这种情况下不会复制引用:
public static void Add<T>(ref T[] _self, T item)
{
Array.Resize(ref _self, _self.Length + 1);
_self[_self.Length - 1] = item;
}
我相信 _self =
将 _self
对象的副本创建到为参数 _self
创建的局部变量中 - 因此不会更新原始对象。使用像列表这样的引用类型,或者创建一个 returns 新数组的静态方法。
根据 'feel' 的原因:您在变量实例上调用方法 - 您不能从在它的上下文下执行的代码中更改该实例
您可以这样更改代码:
public static class Extensions
{
public static T[] Add<T>(this T[] _self, T item)
{
return _self.Concat(new T[] { item }).ToArray();
}
}
public class Program
{
public static void Main()
{
string[] test = { "Hello" };
test = test.Concat(new string[] { "cruel" }).ToArray();
test = test.Add("but funny");
Console.WriteLine(String.Join(" ", test) + " world");
}
}
附带说明 - 用法与 Concat 方法相同。