2013/01/30(Wed) 16:25:00 編集(投稿者)
■No65036 (魔界の仮面弁士 さん) に返信
> ということは、初見なのは「Of 」の事でしょうか?
> だとすれば、これは「ジェネリック」という機能で、VB2005 から追加された機能です。
> 特に、List(Of ) クラスや Dictionary(Of ) クラスなどは出番の多い機能なので、
> 興味があれば調べてみてください。
はい、そのとおりです。
この後大元の実装の際に、事前準備で調査してから着手しようと思います。
途中で変更、修正した個所も含めて、再度コードを展開して
今回の結びとさせていただきます。
魔界の仮面弁士さんありがとうございました。
複数の構造体から1つの構造体にコピー、または1つの構造体から複数の構造体にコピーする手法
手法@:shuさん作のコードNo65007
手法A:魔界の仮面弁士さん作の以下のコード
Imports System.Reflection
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Runtime.CompilerServices
Public Structure AAA
<VBFixedString(2)> Public aaa As String
<VBFixedString(3)> Public bbb As String
<VBFixedString(5)> Public ccc As String
End Structure
Public Structure BBB
<VBFixedString(3)> Public zzz As String
<VBFixedString(5)> Public yyy As String
<VBFixedString(2)> Public xxx As String
End Structure
Public Structure CCC
<VBFixedString(2)> Public Field1 As String
<VBFixedString(3)> Public Field2 As String
<VBFixedString(5)> Public Field3 As String
<VBFixedString(3)> Public Field4 As String
<VBFixedString(5)> Public Field5 As String
<VBFixedString(2)> Public Field6 As String
End Structure
Public Structure DDD
<VBFixedString(1000)> Public Field As String
End Structure
Module Module1
Sub Main()
'文字列から構造体を作れます。
Dim a1 As AAA = StructureFromString(Of AAA)("XXYYYZZZZZ")
Console.WriteLine("=== AAA ===")
Console.WriteLine("aaa=[" & a1.aaa & "]")
Console.WriteLine("bbb=[" & a1.bbb & "]")
Console.WriteLine("ccc=[" & a1.ccc & "]")
'構造体メンバーを繋げて一つの文字列にできます。
Dim strW As String = StructureToString(a1)
Console.WriteLine("[" & strW & "]")
'文字列を経由することで、別の構造体から取得することもできます。
Dim b1 As BBB = StructureFromString(Of BBB)(StructureToString(a1))
Console.WriteLine("zzz=[" & b1.zzz & "]")
Console.WriteLine("yyy=[" & b1.yyy & "]")
Console.WriteLine("xxx=[" & b1.xxx & "]")
'文字列化して再代入すると、長さ調整ができます。
Dim a2 As AAA
a2.aaa = "Long Text"
a2.bbb = "全+半"
a2.ccc = "短い"
Console.WriteLine("=== 長さ調整前 ===")
Console.WriteLine("aaa=[" & a2.aaa & "]")
Console.WriteLine("bbb=[" & a2.bbb & "]")
Console.WriteLine("ccc=[" & a2.ccc & "]")
Console.WriteLine("=== 長さ調整後 ===")
a2 = StructureFromString(Of AAA)(StructureToString(a2))
Console.WriteLine("aaa=[" & a2.aaa & "]")
Console.WriteLine("bbb=[" & a2.bbb & "]")
Console.WriteLine("ccc=[" & a2.ccc & "]")
'複数の構造体を結合して、別の構造体に入れることも簡単にできます。
Dim a3 As AAA
a3.aaa = "Long Text"
a3.bbb = "全+半"
a3.ccc = "短い"
Dim b3 As BBB = StructureFromString(Of BBB)("zzzYYYYYxx")
Dim c3 As CCC = StructureFromString(Of CCC)(StructureToString(a3) & StructureToString(b3))
Console.WriteLine("=== CCC ===")
Console.WriteLine("Field1=[" & c3.Field1 & "]")
Console.WriteLine("Field2=[" & c3.Field2 & "]")
Console.WriteLine("Field3=[" & c3.Field3 & "]")
Console.WriteLine("Field4=[" & c3.Field4 & "]")
Console.WriteLine("Field5=[" & c3.Field5 & "]")
Console.WriteLine("Field6=[" & c3.Field6 & "]")
'構造体DDDに複数の構造体(AAA、BBB)の内容をコピーする。
Dim d4 As DDD = StructureFromString(Of DDD)(StructureToString(a3) & StructureToString(b3))
Console.WriteLine("=== DDD ===")
Console.WriteLine("Field=[" & d4.Field & "]")
strW = StructureToString(d4)
'複数の構造体(AAA、BBB)に、構造体DDDの内容をコピーする。
'開始位置を指定を渡さないStructureFromString
Dim strW1 As String = Mid(strW, 1)
Dim a5 As AAA = StructureFromString(Of AAA)(strW1)
Dim strW2 As String = Mid(strW, Len(a5) + 1)
Dim b5 As BBB = StructureFromString(Of BBB)(strW2)
'開始位置を指定を渡すStructureFromString
Dim a6 As AAA = StructureFromString(Of AAA)(strW)
Dim b6 As BBB = StructureFromString(Of BBB)(strW, Len(a5))
End Sub
'VBFixedString 属性の付いたフィールドを連結し、その文字列を返します。
Public Function StructureToString(Of T As Structure)(ByVal Stx As T) As String
Dim sb As New StringBuilder()
For Each f As FieldInfo In GetType(T).GetFields()
Dim o() As Object = f.GetCustomAttributes(GetType(VBFixedStringAttribute), False)
If o.Length <> 0 Then
Dim attr As VBFixedStringAttribute = DirectCast(o(0), VBFixedStringAttribute)
Dim strW As String
strW = Strings.Left(CStr(f.GetValue(Stx)) & StrDup(attr.Length, " "c), attr.Length)
sb.Append(strW)
End If
Next
Return sb.ToString()
End Function
Public Function StructureFromString(Of T As Structure)(ByVal str As String) As T
Dim newValue As ValueType = StructureFromString
str &= StrDup(Len(newValue), " "c)
Dim pos As Integer = 1
For Each f As FieldInfo In newValue.GetType().GetFields()
Dim attributes() As Object = f.GetCustomAttributes(GetType(VBFixedStringAttribute), False)
If attributes.Length <> 0 Then
Dim attr As VBFixedStringAttribute = DirectCast(attributes(0), VBFixedStringAttribute)
Dim value As String = Strings.Mid(str, pos, attr.Length)
f.SetValue(newValue, value)
pos += attr.Length
End If
Next
Return DirectCast(newValue, T)
End Function
Public Function StructureFromString(Of T As Structure)(ByVal str As String, ByVal intStart As Integer) As T
Dim newValue As ValueType = StructureFromString
str &= StrDup(Len(newValue), " "c)
Dim pos As Integer = 1
For Each f As FieldInfo In newValue.GetType().GetFields()
Dim attributes() As Object = f.GetCustomAttributes(GetType(VBFixedStringAttribute), False)
If attributes.Length <> 0 Then
Dim attr As VBFixedStringAttribute = DirectCast(attributes(0), VBFixedStringAttribute)
Dim value As String = Strings.Mid(str, intStart + pos, attr.Length)
f.SetValue(newValue, value)
pos += attr.Length
End If
Next
Return DirectCast(newValue, T)
End Function
End Module