回答編集履歴

5

少し修正

2020/05/08 07:45

投稿

退会済みユーザー
test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- はまってるのはジェネリック型指定の辺りだと思うので、ジェネリック型をやめてみたらどうでしょう。ジェネリック型はコンパイル時点で型を決定する必要があります。また、
5
+ はまってるのはジェネリック型指定の辺りだと思うので、ジェネリック型をやめてみたらどうでしょう。ジェネリック型はコンパイル時点で型を決定する必要があります。
6
6
 
7
7
  こういう感じなら動くかな。
8
8
 

4

少し修正

2020/05/08 07:45

投稿

退会済みユーザー
test CHANGED
@@ -2,13 +2,15 @@
2
2
 
3
3
 
4
4
 
5
- はまってるのはジェネリック型指定の辺りだと思うので、ジェネリック型をやめてみたらどうでしょう。ジェネリック型はコンパイル時点で型を決定する必要があります。
5
+ はまってるのはジェネリック型指定の辺りだと思うので、ジェネリック型をやめてみたらどうでしょう。ジェネリック型はコンパイル時点で型を決定する必要があります。また、
6
6
 
7
7
  こういう感じなら動くかな。
8
8
 
9
9
  1バイト目の値を0, 1, 2に書き換えると、違う構造体が返ってくるのが確認できます。
10
10
 
11
11
  補足すると、Marshal.AllocHGlobalは後方互換性のためのメモリ確保方法なので、特別な理由が無い限りはMarshal.AllocCoTaskMemかGCHandle.Allocを使用した方が良いでしょう。
12
+
13
+ あと、クラスと構造体は異なるものなので、きちんと単語の使い分けをしてください。
12
14
 
13
15
 
14
16
 

3

補足追加

2020/05/08 05:15

投稿

退会済みユーザー
test CHANGED
@@ -7,6 +7,8 @@
7
7
  こういう感じなら動くかな。
8
8
 
9
9
  1バイト目の値を0, 1, 2に書き換えると、違う構造体が返ってくるのが確認できます。
10
+
11
+ 補足すると、Marshal.AllocHGlobalは後方互換性のためのメモリ確保方法なので、特別な理由が無い限りはMarshal.AllocCoTaskMemかGCHandle.Allocを使用した方が良いでしょう。
10
12
 
11
13
 
12
14
 

2

回答内容を質問の修正に合わせて変更

2020/05/08 04:56

投稿

退会済みユーザー
test CHANGED
@@ -1 +1,161 @@
1
- そもそもbyteはbyteでクラスではないので変換できません。バイト値を判定し、それに対応したクラスをnewして返せば良いと思います。
1
+ ~~そもそもbyteはbyteでクラスではないので変換できません。バイト値を判定し、それに対応したクラスをnewして返せば良いと思います。~~
2
+
3
+
4
+
5
+ はまってるのはジェネリック型指定の辺りだと思うので、ジェネリック型をやめてみたらどうでしょう。ジェネリック型はコンパイル時点で型を決定する必要があります。
6
+
7
+ こういう感じなら動くかな。
8
+
9
+ 1バイト目の値を0, 1, 2に書き換えると、違う構造体が返ってくるのが確認できます。
10
+
11
+
12
+
13
+ ```C#
14
+
15
+ using System;
16
+
17
+ using System.Collections.Generic;
18
+
19
+ using System.Runtime.InteropServices;
20
+
21
+
22
+
23
+ namespace ConsoleApp1
24
+
25
+ {
26
+
27
+ class Program
28
+
29
+ {
30
+
31
+ public enum StructType : byte
32
+
33
+ {
34
+
35
+ AProduct = 0,
36
+
37
+ BProduct,
38
+
39
+ CProduct
40
+
41
+ }
42
+
43
+
44
+
45
+ interface IProduct { }
46
+
47
+
48
+
49
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
50
+
51
+ struct AProduct : IProduct
52
+
53
+ {
54
+
55
+ byte A;
56
+
57
+ }
58
+
59
+
60
+
61
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
62
+
63
+ struct BProduct : IProduct
64
+
65
+ {
66
+
67
+ byte A;
68
+
69
+ byte B;
70
+
71
+ }
72
+
73
+
74
+
75
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
76
+
77
+ struct CProduct : IProduct
78
+
79
+ {
80
+
81
+ byte A;
82
+
83
+ byte B;
84
+
85
+ byte C;
86
+
87
+ }
88
+
89
+
90
+
91
+ static Dictionary<StructType, Type> _DicProductType = new Dictionary<StructType, Type>()
92
+
93
+ {
94
+
95
+ {StructType.AProduct, typeof(AProduct)},
96
+
97
+ {StructType.BProduct, typeof(BProduct)},
98
+
99
+ {StructType.CProduct, typeof(CProduct)}
100
+
101
+ };
102
+
103
+
104
+
105
+ static IProduct GetProductDetail(byte[] bytes, Type type)
106
+
107
+ {
108
+
109
+ GCHandle gch = GCHandle.Alloc(bytes, GCHandleType.Pinned);
110
+
111
+ IProduct result = (IProduct)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), type);
112
+
113
+ gch.Free();
114
+
115
+ return result;
116
+
117
+ }
118
+
119
+
120
+
121
+ static IProduct GetProduct(byte[] bytes)
122
+
123
+ {
124
+
125
+ StructType stype = (StructType)bytes[0];
126
+
127
+ if (!_DicProductType.ContainsKey(stype))
128
+
129
+ {
130
+
131
+ throw new NotImplementedException("Undefined Structure");
132
+
133
+ }
134
+
135
+
136
+
137
+ return GetProductDetail(bytes, _DicProductType[stype]);
138
+
139
+ }
140
+
141
+
142
+
143
+ static void Main(string[] args)
144
+
145
+ {
146
+
147
+ var bytes = new byte[] { 0x00, 0x10, 0x20 };
148
+
149
+ var product = GetProduct(bytes);
150
+
151
+ Console.WriteLine(product);
152
+
153
+ }
154
+
155
+ }
156
+
157
+ }
158
+
159
+
160
+
161
+ ```

1

少し修正

2020/05/08 04:44

投稿

退会済みユーザー
test CHANGED
@@ -1 +1 @@
1
- そもそもbyteはbyteでクラスではないので変換できません。バイト値を判定し、クラスをnewして返せば良いと思います。
1
+ そもそもbyteはbyteでクラスではないので変換できません。バイト値を判定し、それに対応したクラスをnewして返せば良いと思います。