在C#中使用定长数组的操作方法

3

我对C#很陌生,但在ActionScript 3方面有扎实的基础。

在AS3中,你可以这样定义一个数组:

var array:Array = [];

然后通过push()向该数组添加无限数量的项:

array.push(1);

我发现在C#中,你需要为一个数组定义一个永久的长度(我想是这样的),例如:

string[] array = {"this","has","a","length","of","six"};

或者:

string[] array = new string[6];

如果我尝试向该数组添加新项,而这些项的位置超出了该数组的长度,则会出现错误:
array[6] = "failure";

我发现在数组中自由添加/删除项目与现在必须定义最大长度之间存在困难。

当一个数组可能包含0到10000个实体时,在游戏环境中应该如何处理这个问题,我不是很确定。

  1. 我是否应该将数组长度设置得非常长,以适应所有实际实体数?
  2. 是否有一种不同的方式来存储我的实体,应该在C#中使用,但我不知道?
  3. 我是否需要编写自己的类,重新声明具有新长度的数组,并将旧数组中的对象复制到新数组中,留下1个空闲插槽?

任何建议都将是有帮助的!

7个回答

6

C#中的数组大小是固定的,正如你已经发现的那样;调整数组大小 引用了一个指定大小的新数组实例,并将数组中的项目复制到新引用的实例中。

在.NET中,你需要寻找的是 泛型集合,例如 List<T>,其中 T 是某种类型的泛型类型参数。在你所强调的特定情况下,你应该使用 List<string>

var strings = new List<string>();

现在你可以使用 Add() 将字符串添加到集合中。
strings.Add("string to add");

在C#3中,集合初始化器被引入,以便您可以更简洁地初始化集合。
var strings = new List<string> { "string1", "string2", "string3" };

当您创建一个泛型集合的实例时,它会从默认大小开始;在.NET 4中,List<T>的默认大小为0,但是当添加第一项时,它会增加到4(不同的集合类型和框架版本可能具有不同的默认大小,因此默认大小似乎是一种实现细节)。通常,框架使用加倍策略来调整集合的大小,也就是说,当集合已达到容量并且正在尝试添加另一个项目时,集合容量通常会加倍 - 这是在泛型集合的实现中处理的,您不需要担心。
当您要向集合添加已知数量的项目或者知道要添加多少项目的数量级时,您可能需要考虑使用带有int参数的List<T>的重载构造函数来设置默认大小。
var strings = new List<string>(500);

谢谢你的回答,它涵盖了我很可能在未来会问到的一些问题。 - Marty

2
根据您的具体需求,您可能可以使用 List<T> 来代替。
var list = new List<string> { "this", "has", "a", "length", "of", "six" };
list.Add("success");
list[5] = "seven";

Console.WriteLine(list.Count);    // 7

2
请查看System.Collections.Generic中的List<T>。它是一个包含类型为T的对象的动态数组。您可以通过索引添加内容和访问项目。
using System.Collections.Generic;

// ...

List<int> L = new List<int>();
L.Add(1);
L.Add(99);
Console.WriteLine(L.Count); // prints 2
Console.WriteLine(L[0]);    // prints 1

1

Dictionary是JavaScript/ActionScript关联数组的最直接类比 - 允许稀疏索引,但没有有意义的迭代0,1,....n。SortedDictionary也可以是一个选择。

如果您需要一个仅增长并包含所有条目的普通数组 - List<T>


1

浏览System.Collections.Generic中的所有类和接口。 List<T>Dictionary<TKey, TValue> 值得特别关注,但其他内容可以在学习更多后再详细了解。你会发现你经常使用列表和字典。固定长度数组仍然有它们的位置,但如果你从ECMA-Script的变体(如Actionscript)开始,可能需要一段时间才能看到它们限制所带来的力量。希望你不会过度狂热地使用它们,因为它们在某些情况下可能快几个纳秒 ;)

在第一次阅读时忽略“扩展方法”部分。那里的东西真的非常有用,所以稍后要好好学习,但你不想被信息淹没而记不住任何东西。

自从.NET2.0以来,System.Collections使用较少,因为在很多情况下我们不得不用它们,但System.Collections.Generic中的那些更合适。System.Collections中的其他命名空间也充满了好东西,但一旦你理解了列表和字典(对于System.Collections.Concurrent而言,还需要一些多线程概念),理解它们的重点会更容易。


0

在编程中,应该使用 System.Collections.Generic 命名空间中的 List< someType > 而不是固定大小的数组。这个集合将按照您习惯的方式工作--允许您在运行时动态添加/删除项目,而不会限制您的大小。您可以使用 Add()、Insert()、AddAt()、Remove()、RemoveAt() 等许多其他方法。好处是,它也很好地与 Linq 函数配合使用。

myList.Where( itm=>itm.PlayerName == "Steve" ) // for example

这里是 List<T>MSDN 文档,页面底部有一个很好的综合 Linq 操作列表。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接