我正在做一些数据解析并遇到了这个问题。假设我们要将一些byte[]
解析为结构。我想将执行此操作的C#代码包装到静态方法中。
原始代码(我正在修改一块)读取:
public class DiagnosticUndefined : BaseDiagnostic
{
StructDiagnosticUndefined bufferAllocation;
public DiagnosticUndefined(byte[] buff)
{
bufferAllocation = (StructDiagnosticUndefined)DiagnosticUtil.parseStruct(buff, typeof(StructDiagnosticUndefined));
}
}
我想使用通用函数,但如何继续?考虑:
public static class Util {
public static T Convert<T>(byte[] data) {...}
public static void Convert<T>(byte[] data, out T structure) {...}
}
第一个是内联正常程序但是有一个缺点,编译器无法推断数据类型所以我的调用将如下所示:
SomeStruct s;
s = Util.Convert<SomeStruct>(data);
另一种方法是:
SomeStruct s;
Util.Convert(data, out s);
我喜欢第二种方法,因为它将类型推断委托给编译器,即运行时错误更少。另一方面,我倾向于避免使用MSDN支持的out参数:http://msdn.microsoft.com/en-us/library/ms182131.aspx。我全都是为了“不以复杂的方式解决简单的问题”范式,但这次我无法区分......
任何提示,意见?
更新
代码示例被简化,变量实际上是一个成员,所以我不能去“一行”。我也使用编组将数据转换为结构:
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
T output = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
答案 0 :(得分:2)
我会将第一个修改为:
SomeStruct s = Util.Convert<SomeStruct>(data);
然后继续。
原因是阅读和维护的代码较少。
答案 1 :(得分:1)
编辑推荐@Nebula
第一种情况,似乎完全有效:
var s = Util.Convert<SomeStruct>(data);
如果您希望从通话中退回某些信息,请使用out
,但出于声明目的,请不。
答案 2 :(得分:1)
这两种方法都不用创建SomeStruct
对象:
SomeStruct s = new SomeStruct();
因为我相信你在Convert
方法中创建了这个对象。对于第二种方法,正确性应该是:
SomeStruct s;
Util.Convert(data, out s);
因为out
参数不需要初始化。如果您只更改s
的属性并且不更改指针或在Convert
内创建对象,则也不需要out
:
SomeStruct s = new SomeStruct();
Util.Convert(data, s);
恕我直言,方法1应该更好,更具可读性。
答案 3 :(得分:0)
我很确定在这种情况下使用泛型不会给你带来太大的好处。但如果你坚持......
有什么问题var s = Util.Convert<SomeStruct>(d);
此外,转换和解析不是一回事,不要互换使用。