使用时List<T>.ForEach
传递的对象是j
通过引用还是通过值传递的,即下面的示例中的对象?
MyList.ForEach( j => {} );
如果我要做类似的事情:
MyList.ForEach( j => {
j.someOtherList.Add("value");
});
这是作用于原始对象的副本j
还是作用于原始对象?
使用时List<T>.ForEach
传递的对象是j
通过引用还是通过值传递的,即下面的示例中的对象?
MyList.ForEach( j => {} );
如果我要做类似的事情:
MyList.ForEach( j => {
j.someOtherList.Add("value");
});
这是作用于原始对象的副本j
还是作用于原始对象?
根本没有传入一个对象- 有一个type的值T
。如果T
是引用类型,则该值是引用。值是按值传递的,就像平常一样。
现在假设T
某个引用类型带有一个名为 的成员someOtherList
,那么您的代码确实会影响 的值所引用的对象j
- 但 的值j
只是一个引用。列表中的值将是相同的引用,因此如果您随后(例如)再次遍历列表,您将能够看到效果。
重要的是,如果您将代码更改为:
MyList.ForEach( j => {
j = new WhateverYourTypeIs()
});
这根本不会影响清单。
我怀疑您可能对按值传递和按引用传递的工作方式有些困惑,尤其是在 C# 的上下文中。我有一篇关于该主题的文章,可能会对您有所帮助。
这是一种评论(太长,无法放入评论字段)。
Jon Skeet 已经给出了答案:它是“正常”传递的,即按值传递,其中值是值类型的整个对象本身,而值是对引用类型的对象“位置”的引用。因此,问题中的示例很可能“起作用”(假设它someOtherList
是 of 类型的引用类型成员j
)。
但只是为了好玩,我写了一个替代方案ForEachByRef
,它是 by-ref:
public delegate void ActionByRef<J>(ref J j);
public static class MyExtensions
{
public static void ForEachByRef<T>(this List<T> list, ActionByRef<T> action)
{
for (int i = 0; i < list.Count; ++i)
{
T t = list[i];
action(ref t);
list[i] = t;
}
}
}
然后这个工作:
static void Main()
{
var testList = new List<string> { "alpha", "bravo", "charlie", };
testList.ForEachByRef((ref string j) => { j = "changed"; });
}
(我不建议实际使用ForEachByRef
“真实”代码中的方法;这只是为了说明。)