【发布时间】:2012-09-05 04:58:14
【问题描述】:
我正在做一些数据解析并遇到了这个问题。假设我们想将一些 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。我完全赞成“不要以复杂的方式解决简单问题”的范式,但这次我无法区分......
有什么提示、意见吗?
更新
代码示例被简化,变量实际上是一个成员,所以我不能“单行”。我也在使用 Marshalling 将数据转换为结构:
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
T output = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
【问题讨论】:
-
第一个看起来应该不会比
var s = Util.Convert<SomeStruct>(data);更复杂 -
您说“我喜欢第二种方法,因为它将类型推断委托给编译器,即运行时错误更少”。这句话在这种情况下很奇怪,因为在这两种方法中都不可能因为类型而出现运行时错误。在这两种情况下,编译器都会检查类型是否匹配。
-
@DanielHilgarth 函数版本允许隐式转换,如
decimal d = Util.Convert<int>(data);。 -
@hvd:好的 - 但这仍然不会导致运行时错误。
-
如果
data.Length与int的预期长度不匹配,@DanielHilgarthUtil.Convert<int>可能会引发异常,或者可能返回与Util.Convert<decimal>返回的数据完全不同的数据。错误的数据也是运行时错误,只是不是运行时异常。