繁体   English   中英

我应该使用struct而不是class将项目放入int字典吗

[英]Should I use struct instead of class to put items int dictionary

我有一个自定义Entity类(请参见下面的代码)。 此类的对象被填充到Dictionary集合Dictionary<string, Dictionary <uint,Entity>> dt 有人问我使用Struct而不是Class,因为值类型不会复制到堆中。 好吧,我认为在这种情况下,Class似乎是更好的选择,因为Dictionary将仅包含对Entity类型对象的引用。 在这种情况下,实体类型代表csv文件中的一行。 因此,对于每一行,都会有一个Entity类型的对象。 实体类型中封装的Dictionary包含键,值对,它们表示csv文件中一行的列,值。

但是我想确保我没有错过任何明显的事情,所以最好问一下。

 public class Entity
    {
        Dictionary<string, string> dtValues = new Dictionary<string,string>(); //contains values    from CSV file.
        public Dictionary<string, string> Values
        {
          get { return dtValues; }
          set { dtValues = value; }
        }

    }

有人问我使用Struct而不是Class,因为值类型不会复制到堆中。

那个人完全是错的。 简而言之:字典本身在堆上,因此其内容也将在堆上。

如果您不确定应该使用引用类型还是值类型,则应该研究两者的利弊(我在此处列出了一些)。 但是您可能应该使用引用类型。

请记住:过早的优化是万恶之源。

使用结构字典总是一个非常不好的主意,因为当您枚举它或对其值进行任何处理时,您将一遍又一遍地复制数据,因此使用类是正确的方法,以这种方式仅移动引用。

为了封装状态而持有对可变对象的引用的类型通常应避免将那些对象暴露给外部代码。 我不太了解您的Entity类型的目的是什么,因为唯一明显的内容是对Dictionary的引用(当然,它是可变类型)。

通常,如果希望将事物存储在集合中并试图决定使用类或结构来存储事物,我建议以下几点:

  1. 如果对列表项或词典 (不是键)使用可变的类类型,则可以编辑存储在项中的信息,而不必在过程中涉及集合本身。 但是,使项目中包含的信息对外部代码可用,将需要克隆数据项目或将数据从其中复制到其他内容中。

  2. 如果对存储在集合中的东西使用不可变的类类型或任何结构类型,则编辑项中包含的信息将需要读出该项,生成更改的版本并将其存储回去。 但是,使包含在项目中的信息可用于外部代码会容易得多,因为人们可以将其作为自己的数据类型返回。

  3. 有时有用的模式是定义可变结构类型,然后定义包装器类型,如下所示:

     public class ExposedFieldHolder<T> { public T Value; ExposedFieldHolder(T value) { Value = value; } } 

如果Value是一个字段而不是一个属性,并且创建了例如Dictionary<string, ExposedFieldHolder<someStruct>> ,则可以在将数据存储在字典中时编辑数据, eg myDict [“ George”]。Value。年龄++; but it will also be possible to give the data associated with an entry to outside code [eg返回myDict [name] .Value;`]。

与简单地使用可变类相比,将简单的暴露域结构封装在ExposedFieldHolder<T>中可以更安全,更方便(因为一个人可以返回持有人的全部Value而无需授予持有人本身的外部代码访问权限),也更方便而不是使用不可变的类或结构(因为无需使用readout-modify-writeback序列即可修改列表项或字典值)。 与仅将裸场结构直接直接存储在集合中相比,它的空间效率较低。 如果不使用`ExposedFieldHolder而直接将暴露字段结构存储为字典值,则上述对George年龄的更新将需要三步过程:

var temp = myDict["George"];
temp.Age++;
myDict["George"] = temp;

但这可能仍比不可变类或所谓的“不可变”结构所要求的要好,例如

var temp = myDict["George"];
temp = new PersonDat(temp.Name, temp.Age+1, temp.FavoriteColor, temp.AstrologicalSign);
myDict["George"] = temp;

请注意,如果使用外露字段结构时始终遵循前一种模式,则该代码将正确,无论该结构包含哪些字段或属性或它们出现的顺序。 相反,在使用后一种模式时,必须非常小心以确保将其值不应更改的任何字段或属性按正确的顺序传递给构造函数。 有些人可能喜欢这种代码。 我认为这太可怕了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM