/// <summary> /// バイト配列内の指定位置にあるバイト列から構造体に変換する /// </summary> /// <param name="value">バイト配列</param> /// <param name="startIndex">value 内の開始位置</param> /// <param name="endian">エンディアン</param> /// <returns></returns> public static object ToStruct(byte[] value, int startIndex, Endian endian, Type type) { if (!type.IsValueType) { throw new ArgumentException(); } // プリミティブ型は専用メソッドへ飛ばす TypeCode code = Type.GetTypeCode(type); switch (code) { case TypeCode.Boolean: return(ToBoolean(value, startIndex, endian)); case TypeCode.Byte: return(value[startIndex]); case TypeCode.Char: return(ToChar(value, startIndex, endian)); case TypeCode.Double: return(ToDouble(value, startIndex, endian)); case TypeCode.Int16: return(ToInt16(value, startIndex, endian)); case TypeCode.Int32: return(ToInt32(value, startIndex, endian)); case TypeCode.Int64: return(ToInt64(value, startIndex, endian)); case TypeCode.SByte: return(value[startIndex]); case TypeCode.Single: return(ToSingle(value, startIndex, endian)); case TypeCode.UInt16: return(ToUInt16(value, startIndex, endian)); case TypeCode.UInt32: return(ToUInt32(value, startIndex, endian)); case TypeCode.UInt64: return(ToUInt64(value, startIndex, endian)); default: break; // 多分その他のstructなので以下処理する } // 構造体の全フィールドを取得 FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); // 型情報から新規インスタンスを生成 (返却値) object obj = Activator.CreateInstance(type); int offset = 0; foreach (FieldInfo info in fields) { // フィールドの値をバイト列から1つ取得し、objの同じフィールドに設定 Type fieldType = info.FieldType; if (!fieldType.IsValueType) { throw new InvalidOperationException(); } object fieldValue = BitConverterEx.ToStruct(value, startIndex + offset, endian, fieldType); info.SetValue(obj, fieldValue); // 次のフィールド値を見るためフィールドのバイトサイズ分進める offset += Marshal.SizeOf(fieldType); } return(obj); }