'out'参数与泛型/模板参数:最佳实践

时间:2012-09-12 08:01:56

标签: c# generics out

我正在做一些数据解析并遇到了这个问题。假设我们要将一些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();

4 个答案:

答案 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);

此外,转换和解析不是一回事,不要互换使用。