Answers:
如果需要动态大小的数组,我将使用List:
List<string> ls = new List<string>();
ls.Add("Hello");
那可能是一个解决方案;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
但是对于动态大小的数组,我也希望列出。
使用LINQ:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
我喜欢使用它,因为它是单行的,并且非常容易嵌入到switch语句,简单的if语句或作为参数传递。
编辑:
有些人不喜欢,new[] { newitem }因为它创建了一个小的单项临时数组。这是使用的版本Enumerable.Repeat,不需要创建任何对象(至少不在表面上-.NET迭代器可能在表下方创建了一堆状态机对象)。
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
而且,如果您确定阵列永远不会null开始,则可以将其简化为:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
请注意,如果要将项目添加到有序集合中,List则可能是所需的数据结构,而不是以数组开头。
在C#中数组是不变的,例如string[],int[]。这意味着您无法调整它们的大小。您需要创建一个全新的阵列。
这是Array.Resize的代码:
public static void Resize<T>(ref T[] array, int newSize)
{
if (newSize < 0)
{
throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
T[] sourceArray = array;
if (sourceArray == null)
{
array = new T[newSize];
}
else if (sourceArray.Length != newSize)
{
T[] destinationArray = new T[newSize];
Copy(sourceArray, 0, destinationArray, 0, (sourceArray.Length > newSize) ? newSize : sourceArray.Length);
array = destinationArray;
}
}
如您所见,它将创建一个具有新大小的新数组,复制源数组的内容并将引用设置为新数组。提示是第一个参数的ref关键字。
有一些列表可以为新项目动态分配新的广告位。例如,这是List <T>。它们包含不可变的数组,并在需要时调整它们的大小(List <T>不是链接列表的实现!)。没有泛型(带有对象数组)的ArrayList是同一件事。
LinkedList <T>是一个实际的链表实现。不幸的是,您只能将LinkListNode <T>元素添加到列表中,因此必须将自己的列表元素包装到此节点类型中。我认为它的使用并不常见。
Aray.Resize可以调整数组的大小而不会丢失其内容。docs.microsoft.com/en-us/dotnet/api/...
您可以使用@Stephen Chung的基于LINQ的逻辑来使用泛型类型创建扩展方法,从而扩展@Stephen Chung提供的答案。
public static class CollectionHelper
{
public static IEnumerable<T> Add<T>(this IEnumerable<T> sequence, T item)
{
return (sequence ?? Enumerable.Empty<T>()).Concat(new[] { item });
}
public static T[] AddRangeToArray<T>(this T[] sequence, T[] items)
{
return (sequence ?? Enumerable.Empty<T>()).Concat(items).ToArray();
}
public static T[] AddToArray<T>(this T[] sequence, T item)
{
return Add(sequence, item).ToArray();
}
}
然后,您可以像这样直接在数组上调用它。
public void AddToArray(string[] options)
{
// Add one item
options = options.AddToArray("New Item");
// Add a
options = options.AddRangeToArray(new string[] { "one", "two", "three" });
// Do stuff...
}
诚然,AddRangeToArray()方法似乎有点过大,因为您与Concat()具有相同的功能,但是通过这种方式,最终代码可以直接“使用”数组,而与此相反:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
如果由于某种原因要处理大量数组而不是列表,则此泛型类型的返回泛型方法Add可能会有所帮助
public static T[] Add<T>(T[] array, T item)
{
T[] returnarray = new T[array.Length + 1];
for (int i = 0; i < array.Length; i++)
{
returnarray[i] = array[i];
}
returnarray[array.Length] = item;
return returnarray;
}
所有建议的答案都与他们希望避免的一样,创建一个新数组并在其中添加新条目,只是损失了更多开销。LINQ并不是魔术,T的列表是一个带有缓冲区空间的数组,该缓冲区空间带有一些额外的空间,以避免在添加项目时调整内部数组的大小。
所有抽象都必须解决相同的问题,创建一个没有空插槽的数组来容纳所有值并返回它们。
如果需要灵活性,可以创建足够大的列表以供使用,然后执行此操作。否则使用数组并共享该线程安全对象。而且,新的Span无需共享列表即可帮助共享数据。
要回答这个问题:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
因此,如果您已有阵列,我的快速解决方法是
var tempList = originalArray.ToList();
tempList.Add(newitem);
现在只需用新阵列替换原始阵列
originalArray = tempList.ToArray();
自.NET Framework 4.7.1和.NET Core 1.0以来,Append<TSource>已添加了一种新方法IEnumerable<TSource>。
使用方法如下:
var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four
请注意,如果要在数组的开头添加元素,则可以改用new Prepend<TSource>方法。
使用扩展方法呢?例如:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
return source.Union(new TSource[] { item });
}
例如:
string[] sourceArray = new []
{
"foo",
"bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);
请注意,这模仿了Linq的Uniion扩展(用于将两个数组合并为一个新数组)的行为,并且需要Linq库起作用。
我同意埃德。C#并不像VB使用ReDim Preserve那样简单。如果没有集合,则必须将阵列复制到更大的阵列中。
ReDim Preserve只需将数组复制到更大的数组即可。没有奇迹般的数组大小调整。
string str = "string ";
List<string> li_str = new List<string>();
for (int k = 0; k < 100; i++ )
li_str.Add(str+k.ToString());
string[] arr_str = li_str.ToArray();
private static string[] GetMergedArray(string[] originalArray, string[] newArray)
{
int startIndexForNewArray = originalArray.Length;
Array.Resize<string>(ref originalArray, originalArray.Length + newArray.Length);
newArray.CopyTo(originalArray, startIndexForNewArray);
return originalArray;
}
为什么不尝试使用Stringbuilder类。它具有.insert和.append之类的方法。您可以在此处了解更多信息:http : //msdn.microsoft.com/zh-cn/library/2839d5h5(v=vs.71).aspx
由于此问题不满意提供的答案,因此我想添加此答案:)
public class CustomArrayList<T>
{
private T[] arr; private int count;
public int Count
{
get
{
return this.count;
}
}
private const int INITIAL_CAPACITY = 4;
public CustomArrayList(int capacity = INITIAL_CAPACITY)
{
this.arr = new T[capacity]; this.count = 0;
}
public void Add(T item)
{
GrowIfArrIsFull();
this.arr[this.count] = item; this.count++;
}
public void Insert(int index, T item)
{
if (index > this.count || index < 0)
{
throw new IndexOutOfRangeException( "Invalid index: " + index);
}
GrowIfArrIsFull();
Array.Copy(this.arr, index, this.arr, index + 1, this.count - index);
this.arr[index] = item; this.count++; }
private void GrowIfArrIsFull()
{
if (this.count + 1 > this.arr.Length)
{
T[] extendedArr = new T[this.arr.Length * 2];
Array.Copy(this.arr, extendedArr, this.count);
this.arr = extendedArr;
}
}
}
}