このまま動作します。
コピぺ、編集して利用するためのコードの断片です。
自由に使って頂いて構いません。
例えば、以下の構造のオブジェクトを、以下のような文字列に変換できます。
オブジェクトの入れ子に対応しています。
デバッカが使えない環境で、オブジェクトの内容をログに出力して、デバック等に使用できます。
オブジェクトの構造.vb
Imports System.Collections.Generic
Class class_1
Public a As List(Of String)
Public b As Integer = 0
Public c As class_1
End Class
変換した文字列
▽(汎用.Form_Test+class_1)-------------------------------
| ▽a(System.Collections.Generic.List`1[System.String])-------------------------------
| | ▽_items(System.String[])-------------------------------
| | |
| | △_items(System.String[])-------------------------------
| |
| | _size(System.Int32) = 3
| | _version(System.Int32) = 0
| | _syncRoot = Nothing
| | a[0](System.String) = "aaa"
| | a[1](System.String) = "bbb"
| | a[2](System.String) = "ccc"
| |
| △a(System.Collections.Generic.List`1[System.String])-------------------------------
|
| b(System.Int32) = 1
| ▽c(汎用.Form_Test+class_1)-------------------------------
| | ▽a(System.Collections.Generic.List`1[System.String])-------------------------------
| | | ▽_items(System.String[])-------------------------------
| | | |
| | | △_items(System.String[])-------------------------------
| | |
| | | _size(System.Int32) = 3
| | | _version(System.Int32) = 0
| | | _syncRoot = Nothing
| | | a[0](System.String) = "ddd"
| | | a[1](System.String) = "eee"
| | | a[2](System.String) = "fff"
| | |
| | △a(System.Collections.Generic.List`1[System.String])-------------------------------
| |
| | b(System.Int32) = 2
| | c = Nothing
| |
| △c(汎用.Form_Test+class_1)-------------------------------
|
|
△(汎用.Form_Test+class_1)-------------------------------
以下コードでオブジェクトを文字列に変換できます。
呼び出しかた.vb
s = ObjectToString(o)
以下の共通処理を任意の場所に貼り付ければそのまま使用できます。
共通処理.vb
Imports System.Text
Imports System.Reflection
''' <summary>
''' 指定されたオブジェクトの内部構造の文字列表現を返却する。
''' </summary>
''' <param name="targetObject">内部構造の文字列表現を取得する対象のオブジェクト</param>
''' <returns>オブジェクトの内部構造の文字列表現</returns>
''' <remarks></remarks>
Public Function ObjectToString(targetObject As Object) As String
Dim buf As New StringBuilder
_ObjectToString("", targetObject, buf, "")
Return buf.ToString
End Function
''' <summary>
''' 指定されたオブジェクトの内部構造の文字列表現を返却する。
''' 内部呼び出し用なので、ObjectToString以外から直接呼び出さない。
''' </summary>
''' <param name="targetFieldName">解析するオブジェクトのフィールド名</param>
''' <param name="targetObject">内部構造の文字列表現を取得する対象のオブジェクト</param>
''' <param name="buf">オブジェクトの内部構造の文字列表現の出力先バッファ</param>
''' <param name="nestString">オブジェクトの入れ子構造を表現するための文字列</param>
''' <remarks></remarks>
Private Sub _ObjectToString(targetFieldName As String, targetObject As Object, buf As StringBuilder, nestString As String)
Try
If nestString.Length >= 200 Then 'ここの数を調整して解析を打ち切る階層の深さを変更しても良い。
Throw New Exception("階層が深すぎるので解析を打ち切ります")
End If
If targetObject Is Nothing Then
buf.AppendLine(nestString + targetFieldName + " = Nothing")
ElseIf targetObject.GetType Is GetType(Byte) OrElse
targetObject.GetType Is GetType(Short) OrElse
targetObject.GetType Is GetType(Integer) OrElse
targetObject.GetType Is GetType(Long) OrElse
targetObject.GetType Is GetType(Single) OrElse
targetObject.GetType Is GetType(Double) OrElse
targetObject.GetType Is GetType(Decimal) OrElse
targetObject.GetType Is GetType(Char) OrElse
targetObject.GetType Is GetType(Boolean) OrElse
targetObject.GetType Is GetType(Date) Then
buf.AppendLine(nestString + targetFieldName + "(" + targetObject.GetType.ToString + ") = " + targetObject.ToString)
ElseIf targetObject.GetType Is GetType(String) Then
buf.AppendLine(nestString + targetFieldName + "(" + targetObject.GetType.ToString + ") = """ + targetObject.ToString.Replace(vbCrLf, vbCrLf + nestString + " ") + """")
ElseIf targetObject.GetType.ToString.IndexOf("System.Collections.Generic.List") = 0 Then
'型:List(Of ...) への対応
'リストの内部情報はType.GetFieldsから解析する事ができないので、自前で解析する。
buf.AppendLine(nestString + "▽" + targetFieldName + "(" + targetObject.GetType.ToString + ")-------------------------------")
For Each field In targetObject.GetType.GetFields(BindingFlags.FlattenHierarchy Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance)
_ObjectToString(field.Name, field.GetValue(targetObject), buf, nestString + "| ")
Next
Dim count = DirectCast(targetObject.GetType.GetProperty("Count").GetValue(targetObject, Nothing), Integer)
For index = 0 To count - 1
Dim param As Object() = {index}
Dim item As Object = targetObject.GetType.GetProperty("Item").GetValue(targetObject, param)
_ObjectToString(targetFieldName + "[" + index.ToString + "]", item, buf, nestString + "| ")
Next
buf.AppendLine(nestString + "|")
buf.AppendLine(nestString + "△" + targetFieldName + "(" + targetObject.GetType.ToString + ")-------------------------------")
buf.AppendLine(nestString)
Else
buf.AppendLine(nestString + "▽" + targetFieldName + "(" + targetObject.GetType.ToString + ")-------------------------------")
For Each field In targetObject.GetType.GetFields(BindingFlags.FlattenHierarchy Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance)
_ObjectToString(field.Name, field.GetValue(targetObject), buf, nestString + "| ")
Next
buf.AppendLine(nestString + "|")
buf.AppendLine(nestString + "△" + targetFieldName + "(" + targetObject.GetType.ToString + ")-------------------------------")
buf.AppendLine(nestString)
End If
Catch ex As Exception
buf.AppendLine(nestString + "▽" + "(解析中に例外発生)-------------------------------")
buf.AppendLine(nestString + "| " + ex.ToString)
buf.AppendLine(nestString + "| " + ex.Message)
buf.AppendLine(nestString + "| " + ex.StackTrace)
buf.AppendLine(nestString + "|")
buf.AppendLine(nestString + "△" + "(解析中に例外発生)-------------------------------")
End Try
End Sub