2

考虑以下场景:

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
}

struct现在,在和之间进行选择的一般建议class是“struct在需要值语义和class引用语义时使用”。我们需要的语义是“引用Wrappee”。但似乎我们仍然可以制作Wrapper一个结构体:复制它的值和复制一个引用是一样的Wrappee,而且复制后的引用将指向同一个对象!开销较低,并且标量替换可能能够将局部变量的开销减少到零。似乎可以在_wrappee.

我错过了什么吗?是否有充分的理由改为Wrapper上课?

如果调用者不是通用的,则有一个:

int Caller(IInterface t) {...}

在这种情况下Wrapper应该是一个类来避免拳击。

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

更新:请参阅MSDN 论坛上的Professional .NET 2.0 Generics和Peter Ritchie,了解第一种情况下没有拳击。

4

3 回答 3

4

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

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

于 2009-07-31T18:03:43.627 回答
2

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

此外,结构通常不受欢迎,除非它们代表数据类型之类的东西,因此选择一个类可能会阻止将来进行不同性质的讨论。

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

于 2009-08-02T00:47:37.633 回答
0

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

于 2009-07-31T18:03:19.447 回答