如何重新考虑此代码?

时间:2009-02-03 12:39:59

标签: .net vb.net refactoring

我正在使用以下函数将DataTable(从数据层传递)中的列映射到对象属性。该函数存在于我正在填充的类中。该类有两个方法:Load()使用值加载对象,LoadAll()返回已填充对象的集合。我希望能够使用相同的代码来填充当前对象或新对象。然而,我对结果不太满意,主要是因为重复这是一个维护噩梦。

Private Function MapDataRowToProperties(ByVal dr As DataRow, ByVal target As Incident) As Incident
            If target.Equals(Me) Then
               Me.ID = Convert.ToInt32(dr.Item("pkIncidentID"))
               Me.Description = dr.Item("IncidentDetail").ToString
               Me.Created = Convert.ToDateTime(dr.Item("CreatedOn"))
               ...
               Return Me
           Else
              Dim NewIncident As New Incident
              NewIncident.ID = Convert.ToInt32(dr.Item("pkIncidentID"))
              NewIncident.Description = dr.Item("IncidentDetail").ToString
              NewIncident.Created = Convert.ToDateTime(dr.Item("CreatedOn"))
              ...
              Return NewIncident
           End If

    End Function

注意:我很清楚ORM工具会为我做这个,我通常使用EntitySpaces,但对于这个项目,我无法这样做。

4 个答案:

答案 0 :(得分:6)

怎么样:

dim Inc as Incident 
if target.Equals(me) then 
   Inc = Me
else
   Inc = new Incident
end if 
'Other code'
return Inc

OTOH如果target.Equals(me)应该只匹配当前对象(在这种情况下你应该使用Is或ReferenceEquals,因为Equals可以被覆盖以返回其他对象的True)并且你正在传递一个新事件(或者在第二种情况下可以修改目标)然后删除if并直接使用目标。

答案 1 :(得分:4)

在我看来,您的IfElse块只是假设现有对象(当前实例)已经通过而另一个通过创建它来覆盖任何传递的引用这一事实不同重新

这似乎是ByRef参数的理想情况,换句话说,让调用代码传递不同的变量,让这个函数在每种情况下以相同的方式工作:

Private Sub MapDataRowToProperties(ByVal dr As DataRow, ByRef target As Incident)
  If target Is Nothing Then
    target = New Incident()
  End If
  'Set properties 
  '...
End Sub

示例调用:

'Usage 1:
MapDataRowToProperties(dr, Me)

'Usage 2:
Dim inc as New Incident()
MapDataRowToProperties(dr, inc)

答案 2 :(得分:1)

你有一个功能试图做的不止一件事,分开你的意图,一切都会变得清晰

Public Class Incident

   Private sub CopyFrom(ByVal dr As DataRow) 
       MapDataRowToProperties(dr, me)
   End Function

   Private Shared Function CreateFrom(ByVal dr As DataRow) As Incident
      Dim NewIncident As New Incident
      MapDataRowToProperties(dr, me)
      Return NewIncident
   End Function

   Private Shared sub MapDataRowToProperties(ByVal dr As DataRow, byval target As Incident) 
      target.ID = Convert.ToInt32(dr.Item("pkIncidentID"))
      target.Description = dr.Item("IncidentDetail").ToString
      target.Created = Convert.ToDateTime(dr.Item("CreatedOn"))
   End Sub
End Class

现在用法变为

   Dim aClass as new Incident
   aClass.CopyFrom(dr)

   Dim aClass as MyClass = Incident.CreateFrom(dr)

答案 3 :(得分:0)

希望这会有所帮助。 (请原谅我的语法错误,自vb编码以来已经很长时间了。)

在通话功能

If target.Equals(Me) Then

    target = MapDataRosToProperties(target,dr)
Else

    Dim target as Incident

    target = MapDataRosToProperties(target,dr)

重构功能

Private Function MapDataRowToProperties(ByVal target as Incident,ByVal dr as DataRow) As Incident

    target .ID = Convert.ToInt32(dr.Item("pkIncidentID"))
    target .Description = dr.Item("IncidentDetail").ToString
    target .Created = Convert.ToDateTime(dr.Item("CreatedOn"))
    ...
    Return target 

End Function