最佳程序实践:字典或同步数组

Sys*_*gon 2 .net c# vb.net

我想知道什么是最好的,或者是否有更多的可能性.我正在从DataBase中检索数据,例如,我需要存储IDS和NAMES.最好将它们存储在具有索引"synchronized"的不同阵列上,例如(Vb.net):

Dim ids As New List(Of Integer)()
Dim sCods As New List(Of String)()

For each elem In dataBaseData
    ids.Add(CInt(elem("id")))
    sCods.Add(elem("cod").ToString())
Next
Run Code Online (Sandbox Code Playgroud)

所以我知道第三个位置上的索引上的id对应于另一个数组上的相同索引.或者最好这样做:

Dim sCods As New Dictionary(Of Integer, String)()

For each elem In dataBaseData
    sCods.Add(CInt(elem("id")), elem("cod").ToString())
Next
Run Code Online (Sandbox Code Playgroud)

现在假设我也必须存储子元素.我的意思是,对于每个id,一个元素列表,所以使用字典将是这样的:

Dim sSubs As New Dictionary(Of Integer, List(Of String))()
Run Code Online (Sandbox Code Playgroud)

对于数组而言:

Dim sSubs() As New List(Of String)()
Dim sOneSub As String = sSubs(idIndex)(subIndex)
Run Code Online (Sandbox Code Playgroud)

然后想象有很多数据需要检索.我把我的例子放在Vb.Net中,但只有例子.

Ste*_*art 5

如您所述,将数据存储在单独的"同步数组"中肯定是不好的做法.有很多原因可能是个坏主意:

  • 它不是自我记录的 - 代码的结构没有任何明显的暗示,一个数组中的第3项存储与另一个数组中第3项相同的对象的数据.因此,明确的唯一方法是在代码中添加注释,说明数据的存储方式和原因.虽然评论肯定是一件好事,但不需要评论就更好了.

  • 您无法轻松引用数据 - 您打算如何从数据访问层返回此数据?您打算如何将其作为参数传递给业务层方法?要获取所有数据,您必须传递所有列表.要从列表传递单个对象的数据,您必须将所有数据作为单独的变量传递.

  • 它不灵活 - 当您以这种方式存储它时,很难向对象添加新属性.例如,现在,您可能只需要存储每个对象的ID和描述,但是当您还需要存储日期时会发生什么?您不仅需要添加新的列表/数组来存储所有已加载对象的日期,而且还必须修复使用和传递数据的所有位置.您如何找到代码中需要修复的所有位置?这也不容易,因为您可以搜索的对象没有特定的数据类型.

  • 它很脆弱 - 由于上面提到的所有原因,以及更多,存储这样的数据将导致错误的代码.如果列表不同步会怎么样?如果您未能在对象中途加载数据会发生什么情况,那么只有部分列表会更新?如果您需要从列表中删除某个项目并且由于某种原因仅在其中一个列表上失败,该怎么办?如果多个线程需要同时修改数据怎么办?如果你不是特别小心,事情就会很容易出错.没有必要让你的代码变得如此脆弱,那么为什么要给自己带来不必要的麻烦呢?

那么什么是更好的解决方案?嗯,这Dictionary绝对是一个更好的选择,但在这种情况下,它可能仍然是错误的.如果您只需要为每个对象存储两个数据元素,则不需要字典.字典的目的是存储键/值对,您需要能够快速访问给定键的值.该字典使用哈希表来索引列表,以使关键查找非常快速.但是如果它没有被正确使用,它实际上可能会降低效率(即更多内存,因为哈希代码生成速度较慢).

存储对象或实体的数据的正确方法(有时在DB设计中调用)是创建一个类.这些类通常称为数据传输对象(DTO)类.例如:

Public Class MyEntity
    Public Property Id As Integer
    Public Property Code As String
End Class
Run Code Online (Sandbox Code Playgroud)

然后,您可以轻松地将数据存储在所需的任何类型的列表中,例如:

Dim entityArray() As MyEntity  ' Arrays are great for storing lists which don't change in length very often
Dim entityList As List(Of MyEntity)  ' Lists are great when the number of items in the list keeps changing
Dim entityDictionary As List(Of Integer, MyEntity)  ' Dictionaries are great when you need to quickly access items by their key (their ID, in this case)
Dim entityQueue As Queue(Of MyEntity)  ' Queues are great when you need to process incoming items in the order that they were received
' Etc.
Run Code Online (Sandbox Code Playgroud)

现在,当您需要返回一个MyEntity对象时,您可以将其返回As MyEntity.当您需要返回它们的列表时,您可以将它们作为单个列表返回.将它们作为参数传递给方法时也是如此.

此外,当您需要向实体添加新属性时,您只需将其添加到DTO类,如下所示:

Public Class MyEntity
    Public Property Id As Integer
    Public Property Code As String
    Public LastModified As Date  ' Hey look! A new field.
End Class
Run Code Online (Sandbox Code Playgroud)

现在,使用该数据类型的所有代码都可以立即访问该新属性.您所要做的就是用数据填充该字段.如果要查找代码中使用该数据类型的所有位置,只需右键单击MyEntity类名,然后从上下文菜单中选择" 查找所有引用"选项.

正如其他人所提到的那样,有可用于创建实体类以及读取和写入数据库的框架.我会说,在我写这篇文章时,实体框架和NHibernate是两个最受欢迎的选项.它们当然值得考虑,但在开始使用它之前,完全理解框架正在做什么以及为什么需要它总是很重要的.因此,在您开始研究偷工减料的方法之前,我建议您至少尝试自己正确地使用数据访问层一段时间.使用框架可以让您的生活更轻松,但是如果您错误地使用任何框架或者出于错误的原因,它们可能会让您的生活变得更加困难,而不是更容易.