2017-05-17 17 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 )enum。 – TnTinMn

+0

あなたはあなたが渡す 'Field'の値をどこで取得していますか? – Enigmativity

答えて

2

使用リフレクション:

私はVB.NETの構文を知らないが、C#では、このようになります:fieldNameは任意入力ですので、あなたがで間違ったfieldName値を防ぐことができます

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

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

nameof()を使用して、常に有効なフィールド名を指定するようにしてください。

typeof(x)の代わりにx.GetType()が必要ですが、コンパイル時のタイプ(常に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