質問するログイン新規登録

質問編集履歴

5

クラス→構造体

2020/05/08 10:01

投稿

daiki002
daiki002

スコア68

title CHANGED
@@ -1,1 +1,1 @@
1
- byte配列をクラスに変換したい
1
+ byte配列を構造体に変換したい
body CHANGED
@@ -90,11 +90,11 @@
90
90
 
91
91
  foreach (var x in products)
92
92
  {
93
- // 1バイト目でクラスを判定する
93
+ // 1バイト目で構造体を判定する
94
94
  var attribute = (IdAttribute)x.GetType().GetCustomAttribute(typeof(IdAttribute));
95
95
  if (attribute.Id == bytes[0])
96
96
  {
97
- // クラスが判定出来たのでデータ部分を変換する
97
+ // 構造体が判定出来たのでデータ部分を変換する
98
98
  var product = GetProductDetail<typeof(x)>(bytes);
99
99
  // ↓ダメだった
100
100
  //var product = GetProductDetail<typeof(x.GetType())>(bytes);
@@ -104,7 +104,7 @@
104
104
  }
105
105
  }
106
106
 
107
- // 一致するクラスがなかった
107
+ // 一致する構造体がなかった
108
108
  return default;
109
109
  }
110
110
 

4

「属性を使わない場合」を追記

2020/05/08 10:01

投稿

daiki002
daiki002

スコア68

title CHANGED
File without changes
body CHANGED
@@ -116,6 +116,48 @@
116
116
  }
117
117
  }
118
118
  }
119
+ ```
119
120
 
121
+ # 属性を使わない場合
122
+ ```C#
123
+ using System;
124
+ using System.Runtime.InteropServices;
120
125
 
126
+ namespace InterfaceTest
127
+ {
128
+ interface IProduct { }
129
+
130
+ struct AProduct : IProduct { }
131
+ struct BProduct : IProduct { }
132
+ struct CProduct : IProduct { }
133
+
134
+ class Program
135
+ {
136
+ /// <summary>
137
+ /// byte[] を class に変換する
138
+ /// </summary>
139
+ static T GetProductDetail<T>(byte[] bytes)
140
+ {
141
+ var length = Marshal.SizeOf(typeof(T));
142
+ var ptr = Marshal.AllocHGlobal(bytes.Length);
143
+ Marshal.Copy(bytes, 0, ptr, length);
144
+ return (T)Marshal.PtrToStructure(ptr, typeof(T));
145
+ }
146
+
147
+ static void Main(string[] args)
148
+ {
149
+ var bytes = new byte[] { 0x00, 0x01, 0x02 };
150
+
151
+ var product = bytes[0] switch
152
+ {
153
+ 0 => (IProduct)GetProductDetail<AProduct>(bytes),
154
+ 1 => (IProduct)GetProductDetail<BProduct>(bytes),
155
+ 2 => (IProduct)GetProductDetail<CProduct>(bytes),
156
+ _ => default
157
+ };
158
+
159
+ Console.WriteLine(product);
160
+ }
161
+ }
162
+ }
121
163
  ```

3

「やりたいこと」を追記

2020/05/08 02:07

投稿

daiki002
daiki002

スコア68

title CHANGED
File without changes
body CHANGED
@@ -1,6 +1,10 @@
1
- # 質問
1
+ # やりたいこと
2
+ JSONであればテキストのシリアライズ、デシリアライズです。
2
- byte配列をクラスに変換するような低レベルプログムを書いています。
3
+ ProtocolBuffersであればバイナリデータシリアイズ、デシリアライズです。
3
4
 
5
+ JSONやProtocolBuffersは型情報がシリアライズされたデータには含まれていませんが、今回はProtocolBuffersに似た形のバイナリデータで1バイト目に型情報が含まれています。
6
+ なので、1バイト目でデータ型を判定してシリアライズ・デシリアライズするようなものを作ろうとしています。
7
+
4
8
  例えば、
5
9
  - byte配列の1バイト目が`0`であれば`AProduct`
6
10
  - byte配列の1バイト目が`1`であれば`BProduct`
@@ -8,7 +12,10 @@
8
12
 
9
13
  のように変換したいです。
10
14
 
15
+
16
+
17
+ # 質問内容
11
- しかし、以下の部分でエラーが出ています。
18
+ 以下の部分でエラーが出ています。
12
19
  どのようにすればこのエラーを解決できますか?
13
20
 
14
21
  ```C#

2

修正

2020/05/08 01:58

投稿

daiki002
daiki002

スコア68

title CHANGED
File without changes
body CHANGED
@@ -77,7 +77,8 @@
77
77
  var products = new List<IProduct>
78
78
  {
79
79
  new AProduct(),
80
- new BProduct()
80
+ new BProduct(),
81
+ new CProduct()
81
82
  };
82
83
 
83
84
  foreach (var x in products)

1

修正

2020/05/08 01:42

投稿

daiki002
daiki002

スコア68

title CHANGED
File without changes
body CHANGED
@@ -84,7 +84,7 @@
84
84
  {
85
85
  // 1バイト目でクラスを判定する
86
86
  var attribute = (IdAttribute)x.GetType().GetCustomAttribute(typeof(IdAttribute));
87
- if (attribute?.Id == bytes[0])
87
+ if (attribute.Id == bytes[0])
88
88
  {
89
89
  // クラスが判定出来たのでデータ部分を変換する
90
90
  var product = GetProductDetail<typeof(x)>(bytes);