有没有一种优雅的方式来编写这段代码?
我继承了一些代码,当我看着它时,它让我感到畏缩。有没有更优雅的方式来编写以下内容?有没有一种优雅的方式来编写这段代码?
Dim myItem As DTO.MyBaseClass = Nothing
Dim myType As String = GetTypeString()
Select Case myType
Case Is = "Case1"
myItem = Bus.BusManager(Of DTO.MyClass1).Read()
Case Is = "Case2"
myItem = Bus.BusManager(Of DTO.MyClass2).Read()
'... etc etc for 30 lines
是否有一种方法可以将字符串映射到类类型,然后只是像这样一行?或者类似的东西?
myItem = Bus.BusManager(Of MappingDealy(myType)).Read()
由于BusManager
是通用类型,因此必须在编译时指定传入Of <type>
的类型。它不像传统参数,您可以在运行时更改。
从你列出的代码BusManager
实际上做了什么还不清楚。如果它所做的只是创建一个Generic类型的实例,那么创建它的人可能不会真正理解泛型。您是否有能力修改BusManager
的工作方式,还是仅限于按原样使用它?
正如@jmoreno提到的,您可以使用反射从包含类型名称的字符串中创建一个类型的实例。下面是如何将工作:
Imports System.Reflection
Imports System.IO
Public Class ObjectFactory
Private Shared Function CreateObjectFromAssembly(ByVal assembly As Assembly, ByVal typeName As String) As Object
' resolve the type
Dim targetType As Type = assembly.GetType(typeName)
If targetType Is Nothing Then
Throw New ArgumentException("Can't load type " + typeName)
End If
' get the default constructor and instantiate
Dim types(-1) As Type
Dim info As ConstructorInfo = targetType.GetConstructor(types)
Dim targetObject As Object = info.Invoke(Nothing)
If targetObject Is Nothing Then
Throw New ArgumentException("Can't instantiate type " + typeName)
End If
Return targetObject
End Function
Public Shared Function CreateObject(ByVal typeName As String) As Object
Return CreateObjectFromAssembly(Assembly.GetExecutingAssembly, typeName)
End Function
Public Shared Function CreateObject(ByVal typeName As String, ByVal assemblyFileName As String) As Object
Dim assemblyFileInfo = New FileInfo(assemblyFileName)
If assemblyFileInfo.Exists Then
Return CreateObjectFromAssembly(Reflection.Assembly.LoadFrom(assemblyFileName), typeName)
Else
Throw New ArgumentException(assemblyFileName + " cannot be found.")
End If
End Function
End Class
在生产应用程序,我可能会设置返回类型为所有的这些方法,我的基类或接口。只要确保你传递完整的typeName
包括命名空间。
有了这一工厂类,那么你的代码的优雅版会是这个样子:
Dim myItem as DTO.MyBaseClass = ObjectFactory.CreateObject("DTO." & GetTypeString())
首先,切勿使用Case Is =
从不初始化Nothing
。因此,一个快速之一将是:
Dim myItem As DTO.MyBaseClass
Select Case GetTypeString()
Case "Case1"
myItem = Bus.BusManager(Of DTO.MyClass1).Read()
' etc etc
但由于您使用的模板,真的没有办法,除非你想使用反射,这是在稍微干净和更短的代码为代价的效率极其低下的映射它。您还可以添加Imports DTO
以保存124个字符,还可以通过总线保存另外120个字符。
你能详细阐述从未使用'的情况是='从不初始化为'没什么'?我对VB比较陌生。 – 2011-05-25 02:51:49
'Case Is = xxx'直接等于'Case xxx',所以没有意义 - 它只是增加了语法噪音。将引用类型初始化为'Nothing'也是毫无意义的,因为这是默认情况下的。有时可以更清楚地将'布尔值'初始化为'假'和数字值为'0',但从不将类型引用为'Nothing'。 – Ryan 2011-05-25 02:53:44
尽管我还不想初始化为Nothing,但他可能会这样做,以避免在赋值“变量”myItem之前使用“变量myItem”的警告。在运行时可能会产生空引用异常。如果你没有,你会得到。这个警告最糟糕的部分是,我要么通过初始化为无效(并仍然“冒险”空引用exc)来抑制它,要么就像'如果myItem IsNot Nothing Then ...' – 2011-05-25 04:22:34
哇,看起来不错,谢谢一堆! – 2011-06-02 19:32:17