当List<>在 C# 中创建 a 的原始类型(例如 a List<int>)时,列表中的元素是按值存储的,还是按引用存储的?
换句话说,C#List<int>等同于 C++std::vector<int>还是 C++ std::vector<shared_ptr<int>>?
当List<>在 C# 中创建 a 的原始类型(例如 a List<int>)时,列表中的元素是按值存储的,还是按引用存储的?
换句话说,C#List<int>等同于 C++std::vector<int>还是 C++ std::vector<shared_ptr<int>>?
A内部List<int>会有一个int[]。通常不需要装箱 - 值直接存储在数组中。当然,如果您选择将List<T>用作非泛型IList,其中 API 是根据 定义的object,则将框:
List<int> list1 = new List<int>();
// No boxing or unboxing here
list1.Add(5);
int x = list1[0];
// Perfectly valid - but best avoided
IList list2 = new List<int>();
// Boxed by the caller, then unboxed internally in the implementation
list2.Add(5);
// Boxed in the implementation, then unboxed by the caller
int y = (int) list2[0];
请注意,短语“通过引用存储”是一个令人困惑的词——“通过引用”一词通常用于参数传递的上下文中,但它有些不同。
因此,虽然 a List<string>(例如)包含一个数组,其中每个元素值都是一个引用,但在 a 中,List<int>每个元素值只是一个int. 唯一涉及的引用是调用者对 的List<int>引用和对数组的内部引用。(数组类型本身总是引用类型,即使元素类型是值类型。)
那么如果你写这样的代码会发生什么:
struct MutableValueType
{
  public int ChangableInt32;
}
static class Program
{
  static void Main()
  {
     var li = new List<MutableValueType>();
     li.Add(new MutableValueType());
     li[0].ChangableInt32 = 42;
  }
}
您会修改结构的副本,还是会更改List<>? 编译器会警告你吗?我想试试这个。
值类型按值存储。(例如原语和结构)引用类型通过引用存储。(例如类)