我正在尝试创建一个代码重复最少的高效类。
我有这个定义:
Public Class Foo
Private _firstName as string = ""
Private _lastName as string = ""
Public Sub New(ByVal userGUID As Guid)
'query DB to get firstName and lastName
Me.New(dt.Rows(0)("FirstName").ToString(),dt.Rows(0)("LastName").ToString())
End Sub
Public Sub New(ByVal firstName As String, ByVal lastName As String)
_firstName = firstName.toUpper()
_lastName = lastName.toUpper()
Validate()
End Sub
Private Sub Validate()
' Throw error if something is wrong
End Sub
End Class
具有 firstName 和 lastName 参数的构造函数是进行验证的端点构造函数。以 userGUID 作为参数的构造函数将查询 DB 以获取名称并调用最终构造函数。这样,所有执行都应该针对实际执行所有验证等的构造函数之一。其背后的想法是,如果我添加新的构造函数,我只需要提取必要的数据(名字/姓氏)并调用最终的构造函数进行验证。
但是,有一个编译错误阻止我在线使用这个系统Me.New(dt.Rows(0)("FirstName").ToString(),dt.Rows(0)("LastName").ToString())
。显然,这一行必须是构造函数中的第一行。但是如果我将其作为第一行,它将破坏验证过程,因为验证会由于没有名字/姓氏而引发错误。我必须查询数据库才能提取该信息。
我知道我可以在这里分配值并从这个构造函数调用验证,但这会有效地将这个构造函数与最后一个构造函数隔离,从而复制代码并增加维护。仅供参考,在下面的示例中,我只有 2 个构造函数,但实际上我还有更多。如果每个人都会做自己的任务,那么它只会增加维护。
那么,有没有办法通过执行一些代码然后调用重载的构造函数来完成我的任务?
感谢您的任何见解
更新 1:
根据 the_lotus 评论,我包括 dt 定义。这个问题有一个解决方法。基本上我会从最终的构造函数中取出验证和赋值,并将其放入一个函数中。所有的构造函数都会调用这个函数,从而消除了链接构造函数的需要。它看起来不错,但我想了解为什么为了链接构造函数,我必须将构造函数调用放在第一行。
这是新代码:
公共类 Foo Private _firstName As String = "" Private _lastName As String = ""
Public Sub New(ByVal userGUID As Guid)
Dim dt As New DataTable
' query DB to get firstName and lastName
' Assume I populate dt with at least one DataRow
AssignAndValidate(dt.Rows(0)("FirstName").ToString(), dt.Rows(0)("LastName").ToString())
'Me.New(dt.Rows(0)("FirstName").ToString(), dt.Rows(0)("LastName").ToString())
End Sub
Public Sub New(ByVal firstName As String, ByVal lastName As String)
AssignAndValidate(firstName, lastName)
End Sub
Private Sub Validate()
' Throw error if something is wrong
End Sub
Private Sub AssignAndValidate(ByVal firstName As String, ByVal lastName As String)
_firstName = firstName.ToUpper()
_lastName = lastName.ToUpper()
Validate()
End Sub
结束类
一个奇怪的更不用说:在线代码转换器(vb.net 到 C#)在转换链式构造函数调用时没有问题,而不是在第一行。C# 代码返回为this.#ctor(dt.Rows(0)("FirstName").ToString(), dt.Rows(0)("LastName").ToString());
但是,如果我尝试转换回 VB.NET,它会失败。