2017-05-17 138 views
1

我有一個大的結構(50+成員)這樣的參考成員的結構:vb.net按名稱從字符串變量

Public Structure DagDay  
    Public DayDate As Date 
    Public DayEcoZone As String 
    Public DayOrd As Boolean 
    Public DayHelg As Boolean 
    Public DayAfton As Boolean 
    Public DayEvent As Boolean 
    Public DayEventText As String 
    Public DayIncVat As Boolean 
    Public DayOmsTot As Integer 
    Public DayOmsCat1 As Integer 
    Public DayOmsCat2 As Integer 
    Public DayOmsCat3 As Integer 
    ..... 
End Structure 
... 
Dim ThisDay as DagDay 

現在,我試圖讓一個功能設定任何特定的成員在變量ThisDay中的值,但我無法弄清楚如何(否則,然後一個大的選擇..案例..)。

Public Function SetValue(ByVal Field As String, ByVal value As VariantType) As Boolean 

Select Case Field 

      Case "DayDate" 
       ThisDay.DayDate = value 
      Case "DayEcoZone" 
       ThisDay.DayEcoZone = value 
      Case "DayOrd" 
       ThisDay.DayOrd = value 
      Case "DayHelg" 
       ThisDay.DayHelg = value 
     ..... 

     End Select 

我希望能夠做這樣的事情(僞代碼):

Public Function SetValue(ByVal Field As String, ByVal value As VariantType) As Boolean 

     ThisDay.[Field] = value 
     Return True 
End Function 

如何使用一個字符串變量在結構中引用的特定成員(場)?

+0

什麼是'VariantType'? – Plutonix

+1

@Plutonix,我認爲這是對[Microsoft.VisualBasic.VariantType](https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.varianttype(v = vs.110).aspx )枚舉。 – TnTinMn

+0

你從哪裏得到你傳入的'Field'的值? – Enigmativity

回答

2

使用反射:

我不知道VB.NET的語法,但在C#這將是這樣的:

static void SetValue(Object parent, Object newFieldValue, String fieldName) { 

    FieldInfo field = parent.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.Instance); 
    field.SetValue(parent, newFieldValue); 
} 

因爲fieldName是任意的輸入,可以通過防止不正確fieldName值使用nameof()確保您始終指定有效的字段名稱。

請注意,我們需要x.GetType()而不是typeof(x),因爲我們需要運行時類型,而不是編譯時類型(始終爲Object)。

即使你有一個價值型struct工作,傳遞值語義並不適用,因爲它的盒裝爲Object(所以它實際上是通過按引用),所以設置字段將作爲儘管它是一個class(參考類型)。

用法:

MyStruct value; 
value.FieldFoo = "hello"; 
SetValue(value, "world", nameof(value.FieldBar)); 
Assert.AreEqual("world", value.FieldBar); 

我VB.NET是有點生疏,但我認爲這將是它:

Public Shared Sub SetValue(parentAs Object, newFieldValue As Object, fieldName As String) 

    Dim field As FieldInfo = parent.GetType().GetField(fieldName, BindingFlags.Public Or BindingFlags.Instance) 
    field.SetValue(parent, newFieldValue) 

End Sub 

VB.NET現在有NameOf算子的工作方式相同作爲C#的。

用法:

Dim value As New MyStruct 
value.FieldFoo = "hello" 
SetValue(value, "world", NameOf(value.FieldBar)) 
Assert.AreEqual("world", value.FieldBar) 
+0

感謝百萬人的快速和優秀的回答,現在就進行測試。 – JoNo

+0

工程就像一個魅力!優秀的解釋!只需要一個「Imports System.Reflection」以及..謝謝! – JoNo