If the purpose of the interface is to hide from consumers the fact that two equivalent objects might be of different classes, it may be a good idea to define a struct which holds a single private field of that interface type and chains to the appropriate methods of the interfaces. Use of such a struct should generally be essentially as efficient as using a variable of the interface type (the main exception would be if the struct ends up being boxed), but would shield client code from seeing the actual type of thing implementing the interface.
For example, one might have a interfaces IReadableMatrix<T>
and IImmutableMatrix<T>
, and corresponding structures ReadableMatrix<T>
and ImmutableMatrix<T>
with read-only members int Height
, int Width
, and T this[int row, int column]
, and ImmutableMatrix<T> AsImmutable();
. Code which uses an ImmutableMatrix<double>
shouldn't care how it's stored; it would be entirely possible that two instances of ImmutableMatrix
might hold references to different implementations of IImmutableMatrix<T>
which report identical content in every cell, but stored things entirely differently. One might be an instance of ArrayBackedMatrix<double>
, which holds a 12x12 array that happens to hold zeroes in every element other than those on the diagonal, while the other might be a DiagonalMatrix<double>
, and use a 12-item array that only stores things on the diagonal (and returns zero in response to a request for any other element). The use of different types to store the array data should be an implementation detail and not exposed to the client.
One slight detail of using a struct to wrap the arrays is that reference-type fields of a default-value structure will be null, but the structure itself will not. It may thus be desirable to either have the struct implement an IsNull
property which returns true
if the backing field is null
, or else have the other struct members check whether the backing field is null and, if so, behave as an empty 0x0 matrix.
AClass
to be equal to similar object of other class (like duck typing ) use second one, first one is close to standard value type behavior forEquals
– Legislate