.NET中的包装器类型:struct还是class?

时间:2009-07-31 17:59:21

标签: .net types wrapper

考虑以下情况:

int Caller1<T>(T t) where T : IInterface {...}
T Caller2<T>() where T : IInterface {...}

class Wrappee // doesn't implement IInterface, but could

??? Wrapper : IInterface {
  private readonly Wrappee _wrappee;

  // methods call _wrappee's methods
}

现在,在structclass之间进行选择的一般建议是“如果您需要值语义而使用struct,并且class用于参考语义”。我们需要的语义是“引用Wrappee”。但似乎我们仍然可以使Wrapper成为一个结构:复制它的值与复制Wrappee引用相同,并且副本将引用相同的对象!开销较低,scalar replacement可能能够将局部变量减少到零。似乎可以在_wrappee上调用甚至是变异方法。

我错过了什么吗?是否有充分理由让Wrapper成为一个班级?

如果来电者不通用,则有一个:

int Caller(IInterface t) {...}

在这种情况下,Wrapper应该是一个避免装箱的类。

对那些了解Haskell的人说:我正在尝试找到与newtype最接近的.NET类似物。

更新:在第一种情况下,请参阅Professional .NET 2.0 GenericsPeter Ritchie on MSDN forums是否缺席拳击。

3 个答案:

答案 0 :(得分:4)

是的,因为您将通过IInterface变量访问包装器,以避免装箱,它应该是一个类。

编辑:如果您通过类型为Wrapper的变量访问包装器,并访问Wrapper方法,而不是IInterface方法,那么结构就可以了。

答案 1 :(得分:2)

通常你的类/结构将通过你调用的方法在内部存储或传递(你没有显示Caller1和Caller2做的事情),在这种情况下它可能会被装箱。可能比你预期的更频繁。因此,除非你能证明结构更有效:不要打扰并坚持使用类。

此外,结构通常不赞成,除非它们代表类似数据类型的东西,所以选择一个类可能会阻止将来讨论不同的性质。

但是,如果性能确实是一个问题,并且如果您可以保证实例仅作为具有泛型类型约束的参数传递,并且从不存储在接口类型的字段或集合中,则.NET运行时当前内联结构将更有效,因为您的包装器结构将大部分被优化掉。但那是很多ifs。

答案 2 :(得分:0)

我会说课,因为你是封装行为,而不仅仅是数据。