我正在尝试创建一个有效的类,尽量减少代码重复。
我有这样的定义:
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())
上使用这个系统。显然,这一行必须是构造函数中的第一行。但是,如果我将它作为第一行,它将中断验证过程,因为验证将引发一个错误,原因是没有名字/姓氏。我必须查询DB才能得到这些信息。
我知道我可以在这里赋值并从这个构造函数调用验证,但这将有效地将这个构造函数与最后一个构造函数隔离开来,从而复制代码并增加一些维护。FYI,在下面的示例中,我只有2个构造函数,但实际上我还有几个构造函数。如果每个人都完成自己的任务,那就意味着要进行如此多的维护。
那么,是否有办法通过执行一些代码,然后调用重载的构造函数来完成我的任务?
谢谢你的洞察力
更新1:
根据the_lotus的评论,我包括dt定义。这个问题有一个解决办法。基本上,我会将验证和赋值从最终的构造函数中提取出来,并将其放入函数中。所有构造函数都将调用此函数,从而消除了链接构造函数的需要。这看起来不错,但我想了解为什么为了链接构造函数,我必须将构造函数调用放在第一行。
以下是新代码:
公共类Foo专用_firstName =“私有_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,它将失败。
发布于 2015-05-11 17:02:18
你要找的是工厂的方法
Public Class Foo
Public Shared Function GetFooFromGuid(ByVal userGUID As Guid) As Foo
' Query db
return New Foo(dt.Rows(0)("FirstName").ToString(), dt.Rows(0)("LastName").ToString())
End Function
End Class
或初始化函数
Public Class Foo
Public Sub New(ByVal userGUID As Guid)
' query DB to get firstName and lastName
Initialize(dt.Rows(0)("FirstName").ToString(), dt.Rows(0)("LastName").ToString())
End Sub
Public Sub New(ByVal firstName As String, ByVal lastName As String)
Initialize(firstName, lastName)
End Sub
Private Sub Initialize(ByVal firstName As String, ByVal lastName As String)
End Sub
End Class
就我个人而言,我不会把数据库称为New。
发布于 2015-05-11 16:13:42
我不喜欢的是,您在构造函数上访问DB,并且在构造函数中进行验证。我认为这是设计问题。下面是3个重载构造函数的例子。三项工作都完成了。您可能需要#3.在静态(vb共享)方法中插入您的dt
。您还可以将fname/lname参数替换为包含这两个参数的一个参数。对你来说,第三种方法是可行的
public class A
{
public A() : this ("xxx")
{
}
public A(string x)
{
}
}
public class A
{
public A()
{
}
public A(string x): this ()
{
}
}
public class A
{
public A() : this(GetXxx())
{
}
public A(string x)
{
}
private static string GetXxx()
{
return "xxx";
}
}
为什么是构造器链接?因为您的对象可以在许多属性中具有默认值,并且可能有许多构造函数,因此每个构造函数都添加了一个属性。在内部,一个构造函数可以设置5个属性,而其他4个构造函数只能设置一个属性。
例如:
public class Door
{
private string _material = "wood";
private int _locks = 1;
private int _hinges = 3;
public Door()
{
}
public Door(int locks) : this()
{
_locks = locks;
}
public Door(int locks, int hinges) : this(locks)
{
_hinges = hinges;
}
}
https://stackoverflow.com/questions/30171642
复制相似问题