C# 列表<;字符串>;传地址
我想知道如何证明.Net框架在幕后做了什么 我有一个方法,它接受C# 列表<;字符串>;传地址,c#,C#,我想知道如何证明.Net框架在幕后做了什么 我有一个方法,它接受列表originalParameterList的参数 在我的方法中,如果我执行以下操作,则会有另一个列表newListObj: List<String> newListObj = originalParameterList newListObj.Add(value); newListObj.Add(value1); newListObj.Add(value2); List newListObj=
列表originalParameterList
的参数
在我的方法中,如果我执行以下操作,则会有另一个列表newListObj
:
List<String> newListObj = originalParameterList
newListObj.Add(value);
newListObj.Add(value1);
newListObj.Add(value2);
List newListObj=originalParameterList
新增(价值);
newListObj.Add(值1);
newListObj.Add(值2);
原始参数列表的计数增加(+3)
如果我这样做:
List<String> newListObj = new List<String>(originalParamterList);
newListObj.Add(value);
newListObj.Add(value1);
newListObj.Add(value2);
List newListObj=新列表(原始参数列表);
新增(价值);
newListObj.Add(值1);
newListObj.Add(值2);
原始参数列表的计数保持不变(+0)
我还发现此代码的行为与此相同:
List<String> newListObj = new List<String>(originalParamterList.ToArray());
newListObj.Add(value);
newListObj.Add(value1);
newListObj.Add(value2);
List newListObj=新列表(originalParameterList.ToArray());
新增(价值);
newListObj.Add(值1);
newListObj.Add(值2);
原始参数列表的计数保持不变(+0)
我的问题是,有没有一种方法可以明确地看到.Net Framework在幕后做了什么?通常,文档应该提供足够的信息来使用API 在您的特定示例中,
public List(IEnumerable collection)
的文档说明(emphasis mine):
初始化包含元素的List类的新实例
从指定集合复制了,并具有足够的容量
容纳复制的元素数
以下是构造函数的源代码供参考:
public List (IEnumerable <T> collection)
{
if (collection == null)
throw new ArgumentNullException ("collection");
// initialize to needed size (if determinable)
ICollection <T> c = collection as ICollection <T>;
if (c == null) {
_items = EmptyArray<T>.Value;;
AddEnumerable (collection);
} else {
_size = c.Count;
_items = new T [Math.Max (_size, DefaultCapacity)];
c.CopyTo (_items, 0);
}
}
void AddEnumerable (IEnumerable <T> enumerable)
{
foreach (T t in enumerable)
{
Add (t);
}
}
公共列表(IEnumerable集合)
{
if(集合==null)
抛出新的ArgumentNullException(“集合”);
//初始化为所需大小(如果可确定)
ICollection c=作为ICollection的集合;
如果(c==null){
_items=EmptyArray.Value;;
可加数(集合);
}否则{
_尺寸=c.计数;
_项目=新T[数学最大值(_大小,默认容量)];
c、 复制到(_项,0);
}
}
void AddEnumerable(IEnumerable可枚举)
{
foreach(可枚举中的T)
{
加(t);
}
}
最简单的方法就是访问MSDN
上面说
初始化List类的新实例,该实例包含从指定集合复制的元素,并具有足够的容量来容纳复制的元素数
因此,在内部,只需将传递的IEnumerable的所有元素添加到新列表中即可。它还说
这是一个O(n)操作
这意味着没有进行任何优化。这是因为在第一种情况下,您引用了原始列表(因为它是引用类型),并且通过newListObj修改了它的集合。第二种和第三种情况是,您通过列表构造函数复制了原始对象的集合,并修改了新集合,这不会对原始集合产生任何影响。正如其他人所说,有各种工具可以让您检查.NET framework的源代码。我个人更喜欢免费的 在您提到的特定情况下,我认为当您将一个列表传递给另一个列表的构造函数时,该列表将被复制。如果您只是将一个变量分配给另一个变量,那么这些变量只是引用同一个列表。您可以
- 反编译生成的MSIL代码,例如使用
- 或者
public List(IEnumerable<T> collection)
{
if (collection == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
ICollection<T> collection2 = collection as ICollection<T>;
if (collection2 != null)
{
int count = collection2.Count;
this._items = new T[count];
collection2.CopyTo(this._items, 0);
this._size = count;
return;
}
this._size = 0;
this._items = new T[4];
using (IEnumerator<T> enumerator = collection.GetEnumerator())
{
while (enumerator.MoveNext())
{
this.Add(enumerator.Current);
}
}
}
公共列表(IEnumerable集合)
{
if(集合==null)
{
ThrowHelper.ThrowArgumentNullException(argument.collection除外);
}
ICollection collection2=作为ICollection的集合;
if(collection2!=null)
{
int count=collection2.count;
此._items=新的T[计数];
collection2.CopyTo(此._项,0);
这个。_size=count;
返回;
}
这个。_size=0;
此._items=新T[4];
使用(IEnumerator枚举器=collection.GetEnumerator())
{
while(枚举数.MoveNext())
{
this.Add(枚举数.Current);
}
}
}
正如您在调用接受IEnumerable的costructor时所看到的,它会将所有数据复制到自身。您可以将程序集加载到ILDASM中,然后(加载时)找到您的方法并双击它, 它将显示该方法的cil代码。只需在windows开始菜单中的搜索中键入“IL” 或者,您也可以使用以下方法创建一个新的独立列表
private void GetList(List<string> lst)
{
List<string> NewList = lst.Cast<string>().ToList();
NewList.Add("6");
//not same values.
//or....
List<string> NewList = lst.ConvertAll(s => s);
NewList.Add("6");
//again different values
}
private void GetList(List lst)
{
List NewList=lst.Cast().ToList();
新列表。添加(“6”);
//不同的值。
//或者。。。。
List NewList=lst.ConvertAll(s=>s);
新列表。添加(“6”);
//又是不同的价值观
}
您可以检查IL。此外,在创建新列表时,您正在传递对该列表的引用。您没有影响原始列表。请仔细阅读。例如,您也可以使用反射器。另一个资源是。请看,由于使用了“new”关键字,因此这里有一个新对象,这一点非常清楚。您可以检查语法并确定它在做什么。“新建”将创建一个新对象。And=将创建一个引用。