试图理解结构.列表引用<>;

本文关键字:lt gt 引用 列表 结构 | 更新日期: 2023-09-27 18:30:01

我有以下代码:

public void Start()
    {
        List<StructCustomer> listCustomer = new List<StructCustomer>();
        listCustomer.Add(
            new StructCustomer { ID = 0, name = "Any Default Name", birthday = DateTime.Now });

        DoSomethingWithStructList(listCustomer);
        StructCustomer customer = listCustomer.First();
        Console.WriteLine("ID = {0}, Name = {1}", customer.ID, customer.name); // Writes ID = 0, Name = "Any Default Name"
    }
public void DoSomethingWithStructList(List<StructCustomer> listStructs)
        {
            StructCustomer test = listStructs.First();
            test.ID = 2;
            test.name = "Edited by method";
            Console.WriteLine("ID = {0}, Name = {1}", test.ID, test.name); // Writes "ID = 2, Name = Edited by method"
        }
 public struct StructCustomer
        {
            public int ID { get; set; }
            public string name { get; set; }
            public DateTime birthday { get; set; }
        }

您可以注意到,变量List是对客户列表的引用。是否应该在列表中的StructCustomer变量中编辑该值?

我知道Structs是值类型,而不是引用类型,但我把它装箱在列表中!

试图理解结构.列表引用<>;

好吧,当你这样做时:

StructCustomer test = listStructs.First();
test.ID = 2;
test.name = "Edited by method";
Console.WriteLine("ID = {0}, Name = {1}", test.ID, test.name);

实际上,您正在创建listStructs中第一个结构的副本,因此,您将更改副本的值,而不是实际值。试着这样做吧——它应该有效:

listStructs.First().ID = 2;
listStructs.First().name = "Edited by method";

所以,就是这样;)OBS:这种方法不建议使用CPU,但它是一种出路=)

结构是值类型,因此,当您从列表中检索它们时,就像在您的示例中一样,您检索的是其值的副本。然后进行修改。这不会更改列表中包含的原始内容中的任何内容。

如果你想更改列表中的元素,可以这样做:

listStructs[0].ID = 2;
listStrings[0].name = "Edited by method";

创建一个结构类型的列表将导致列表中的每个项封装结构中的所有字段。列表的索引"get"方法将把与列表项关联的所有字段复制到返回值的相应字段中;索引的"put"将把传入项中的所有字段复制到与相应列表项关联的相应字段中。请注意,"get"answers"put"都不会在列表中的项目和读取或写入的项目之间创建任何附件;未来对其中一个的更改不会影响另一个。

对于许多类型的程序来说,这种超然有时是可取的,有时则不然。为了帮助简化此类情况,我建议创建一个类型,如:

class SimpleHolder<T> { public T Value; /* A field, not a property! */ }

然后使用CCD_ 1。

您的类应该自己创建每个SimpleHolder<StructCustomer>实例,并且永远不要向外部代码公开对这些实例的引用。如果您想要一种方法,例如退货项目0,请使用:

StructCustomer FirstCustomer()
{ 
  return listStructHolders[0].Value;
}

存储传入值:

void AddCustomer(StructCustomer newCustomer)
{
  var temp = new SimpleHolder<StructCustomer>();
  temp.Value = newCustomer;
  listStructHolders.Add(temp);
}

修改客户3的名称:

listStructHolder[3].Value.name = "Fred";

使用一个简单的"公开字段持有者"类可以很容易地将结构类型和可变类的优点结合起来。

List包含值类型,因此当您向它请求项目时,它会返回一个值。试着做一个列表,你会看到同样的行为。

因此,您需要直接对列表中的列表项进行分配。通过在foreach循环中对列表进行迭代,可以使行为在语义上更接近于您想要做的事情。