Consider the following scenario:
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
}
Now, the general advice for choosing between struct
and class
is "use struct
if you need value semantics and class
for reference semantics". The semantics we need is "reference to Wrappee
". But it seems we can still make Wrapper
a struct: copying its value is the same is the same as copying a Wrappee
reference, and the copies will have a reference to the same object! Overhead is lower and scalar replacement may be able to reduce it to zero for local variables. It seems all right to call even mutating methods on _wrappee
.
Am I missing anything? Is there a good reason to make Wrapper
a class instead?
There is one if the caller isn't generic:
int Caller(IInterface t) {...}
In this case Wrapper
should be a class to avoid boxing.
Remark for those who know Haskell: I am trying to find the closest .NET analogue to newtype
.
UPDATE: See Professional .NET 2.0 Generics and Peter Ritchie on MSDN forums for absence of boxing in the first case.