C# - 实例化字典的最佳方法是什么?

时间:2018-03-17 13:05:39

标签: c# dictionary

最近我一直在关注Unity的一些教程,想要进入一些游戏编程。现在,我注意到教程中的人执行以下操作将参数复制到变量:

private Dictionary<string, Inventory> inventoryRequirements;

public Job ( Dictionary<string, Inventory> inventoryRequirements) {
    this.inventoryRequirements = new Dictionary<string, Inventory>(inventoryRequirements);
}

当然这很好用,但我只是想知道这和下面的区别是什么:

private Dictionary<string, Inventory> inventoryRequirements;

public Job ( Dictionary<string, Inventory> inventoryRequirements) {
    this.inventoryRequirements = inventoryRequirements;
}

3 个答案:

答案 0 :(得分:2)

在第一种情况下,您初始化一个字典实例,该字典包含从您传递给构造函数的字典中复制的元素,并且您使用键类型的默认相等比较器。有关详细信息,请查看here。然后,将新创建的字典的引用分配给inventoryRequirements字段。

而在第二种情况下,您只需将原始字典的引用副本分配给inventoryRequirements字段。

答案 1 :(得分:1)

在第一个示例代码段中,您将使用复制构造函数克隆作为参数传入的字典实例。

而第二种方法,只是将传入的字典引用分配给当前对象字典实例。

第一种方法是克隆给定字典数据的有效方法。这意味着修改原始字典时,副本不会受到影响。

那就是说,如果<?php session_start(); ?> <html> <body> <form action="NoRefreshCalculate.php" method="post"> City name: <input type="text" name="city"><br> <input type="submit" name="submit" value="Search" /> </form> <?php if (isset($_SESSION['page2'])) { # echo results if (isset($_SESSION['city'])) { echo "City name = ".$_SESSION['city']; } session_destroy(); session_start(); $_SESSION['page1']=1; } else { header('Location: NoRefreshForm.php'); } ?> </body> </html> 是一个引用类型(我假设它是),那么重要的是要注意你克隆了字典但是如果你没有克隆Inventory值在字典实例中,仍然可以在给定的Inventory实例字典中看到对Inventory的任何修改。

答案 2 :(得分:0)

嗯,要真正理解究竟发生了什么,让我们看一下快速的代码片段。

观察输出你可以看到,在第二种情况下,你的原始字典实际上已被修改,并且值映射到键&#34; test&#34;被重新分配到0。

正如您可能已经想到的那样,当您使用new Dictionary<string, Inventory>(inventoryRequirements);实际创建原始字典的 clone 时,实例化类可以根据需要修改其副本,而不会影响您的副本

然而,当您直接传递相同的字典时,实例化类所做的任何修改都会在您的课程中显示,并且您将失去对字典的控制权,因为您基本上已经给出了实例化的类完全控制它。

现在,作为OOP的一般规则,您应该保留自己的字段(其他类/对象不需要)。按照这个逻辑,你应该传递你的对象(而不是副本):

  1. 您将不再需要该对象或
  2. 您的对象非常大,无法合理克隆请注意,如果您的对象超出范围,GC会自动删除该对象
  3. 该对象是一个原语(您将获得一个深层副本,因此它已经是一个克隆。)
  4. 现在,如果您不需要上述任何一项,您可能应该传递副本。