有人请说明如何为
实施Add方法(如何在c#中为List实现Add方法)
listobject.Add();
其中List<User> listobject= new List<User>()
是对象的声明。
我知道使用List我们可以快速执行许多操作,而且类型安全也是如此,但我想知道如何实现id add方法,以便在运行时处理所有这些。
希望它不会复制对象并在每次添加时进行调整,但我会保持手指交叉并等待您的回复:)
答案 0 :(得分:6)
使用Reflector,您可以确切了解其实施方式。
public void Add(T item)
{
if (this._size == this._items.Length)
{
this.EnsureCapacity(this._size + 1);
}
this._items[this._size++] = item;
this._version++;
}
关注'EnsureCapacity'......
private void EnsureCapacity(int min)
{
if (this._items.Length < min)
{
int num = (this._items.Length == 0) ? 4 : (this._items.Length * 2);
if (num < min)
{
num = min;
}
this.Capacity = num;
}
}
最后是'容量'的设定者
public int Capacity
{
get
{
return this._items.Length;
}
set
{
if (value != this._items.Length)
{
if (value < this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
}
if (value > 0)
{
T[] destinationArray = new T[value];
if (this._size > 0)
{
Array.Copy(this._items, 0, destinationArray, 0, this._size);
}
this._items = destinationArray;
}
else
{
this._items = List<T>._emptyArray;
}
}
}
}
答案 1 :(得分:3)
List<T>
在内部将项目保存在数组中。实际的实现(List<string>
)是在编译时运行时创建的(感谢@Jason进行更正),因此内部会有一个包含项目的字符串数组。
对于引用类型,列表将包含对您添加的同一对象实例的引用。对于字符串也是如此。但请注意,字符串类是 immutable ,因此每次修改字符串时,实际上都会导致新实例。
string a = "a";
List<string> list = new List<string>();
list.Add(a); // now the item in the list and a refer to the same string instance
a = "b"; // a is now a completely new instance, the list
// is still referring the old one
答案 2 :(得分:1)
不会它会对字符串引用起作用,否则如果它总是克隆你的对象就不会有太多的意义。
您可以通过使用内存屏幕在Visual Studio中实际检查此类事物,可以比较添加项目的地址和原始地址,您将看到它们指向相同的内存位置。
答案 3 :(得分:1)
正如Frederik所说,List在内部使用数组。它创建具有初始大小的数组,并且添加更多项目,如果数组填充到容量,则将其复制到更大的数组中。这就是为什么如果您提前知道List将包含许多字符串,那么可以帮助在constructor中指定其初始容量。
当您从列表中删除项目或在中间插入时,它必须移动内部数组中的所有元素,以便List不会特别优化以添加/删除许多项目。您可能最好使用LinkedList,这在添加/删除操作方面效率更高,但却放弃了按位置有效访问列表中元素的功能。
不同的集合具有最适合某些场景的不同实现。有关如何实现各种集合的一个很好的示例,我建议您查看Wintellect发布的PowerCollections库。许多集合在.NET 3.5 / 4.0中不再相关,但它们提供了一些关于如何实现集合的深刻见解。
答案 4 :(得分:0)
对于List,Add方法将是泛型类型T,在本例中为字符串。列表的内容将是对原始变量的引用,因此如果您修改列表中的字符串,它将修改原始字符串,反之亦然。