使用基于类型的构造函数初始化类中的所有字段

时间:2014-10-20 14:09:59

标签: .net vb.net

我对一个类的初始化有一个小问题,它基本上是一些数据存储的中心访问点。

这不是一个真正的问题"但我正在寻找一种以优雅的方式编写它的方法。

我有一个包含大量字段的课程。每个字段都设置为ReadOnly,并在构造函数内初始化。现在我想要一种初始化此类中所有字段的方法,而无需以明确的方式编写构造函数。主要是因为构造函数在使用的参数方面总是相同的,并且对于每个初始化,需要进行一些错误检查。此外,创建的实例的性质允许我运行那些并行,我希望这样做。

现在我创建了一些很好用的构造......有点:

  Dim myType = [GetType]()
  Dim fields = myType.GetFields(BindingFlags.NonPublic Or BindingFlags.Instance)
  Dim flags = BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance
  Dim culture = Globalization.CultureInfo.InvariantCulture
  Dim params() As Object = {param1, param2, param3}

  Task.WaitAll((From field In fields
                Where GetType(ISomeInterface).IsAssignableFrom(field.FieldType)
                Select Task.Run(Sub()
                                  Try
                                    Dim newInstance = Activator.CreateInstance(field.FieldType, flags, Nothing, params, culture)
                                    field.SetValue(Me, newInstance)
                                  Catch ex As Exception
                                    ReportError(ex)
                                  End Try
                                End Sub)).ToArray)

这件事有效。怎么会有两个问题:

首先,它感觉像是一个黑客。我正在设置一个lambda表达式的只读字段,就像一个内部类。所以我基本上是在课外设置只读字段。这只是错误的,可能会在将来的.NET版本中引起问题。

第二个问题是这个代码是通过混淆器运行的。而这个混淆器有一个明智的想法,即将所有字段类型更改为Object,导致整个事情停止工作。我还是无法让混淆器离开这些领域。但这不是问题。它只显示整个结构容易出错的程度。

有没有更好的"初始化这些字段的方法?

2 个答案:

答案 0 :(得分:0)

  

现在,我想要一种初始化此类中所有字段的方法,而无需以明确的方式编写构造函数。

您是否在VB.NET的语法中寻找类似的东西?

Public Class MyClassWithReadOnlyProperties
  Public ReadOnly Property MyProperty1 As String = "Hello"
  Public ReadOnly Property MyProperty2 As Integer = 1
End Class

我认为它是Visual Studio“14”的一部分,目前正处于CTP4。

但是,您可以使用VS 2013中的字段执行此操作,而不是属性:

Public Class MyClassWithReadOnlyProperties
  Public ReadOnly MyProperty1 As String = "Hello"
  Public ReadOnly MyProperty2 As Integer = 1
End Class

是的,使用反射是一种破解,只应作为最后的手段使用。

答案 1 :(得分:0)

您可以使用Factory方法吗?

Class DemoClass
  Property Prop1 As String
  Property Prop2 As String
  Property Prop3 As String

  Sub New(p1 As String, p2 As String, p3 As String)
    Prop1 = p1
    Prop2 = p2
    Prop3 = p3
  End Sub

  Enum DemoClassTypes_ENUM As Integer
    Dog
    Cat
    Sheep
  End Enum

  Shared Function Factory(classType As DemoClassTypes_ENUM) As DemoClass
    Select Case classType 
      Case DemoClassTypes_ENUM.Cat
        Return New DemoClass("Felix", "Meow", "4") 'Could return a subclass here if you wanted
      Case DemoClassTypes_ENUM.Dog
        Return New DemoClass("Rex", "Woof", "4")
      Case DemoClassTypes_ENUM.Sheep
        Return New DemoClass("Dolly", "Baa", "4")
    End Select
    Return Nothing
  End Function

End Class

用法:

Dim c As DemoClass = DemoClass.Factory(DemoClass.DemoClassTypes_ENUM.Cat)