I have an interface that transforms a grid of data which I want to implement:
public interface ITransformable<T>
{
T Slice(int x, int y, int width, int height);
T Slice(Rectangle value);
T Transpose();
T Flip(bool horizontal, bool vertical);
T Rotate(bool clockwise);
}
So I make a class that does so:
public class Mesh<T> : ITransformable<Mesh<T>>
{
public Mesh<T> Transpose() { ... }
/// etc
}
However, when making a more derived version of mesh, I run into an issue. For example, I have a Heightmap class which is a Mesh<float>. By making a specific implementation of T, this allows me to use operator overloads so I can add easily add two heightmaps together, for example. But when I implement it
public class Heightmap : Mesh<float> { ... }
Heightmap's functions from ITransformable still return a Mesh, rather than a Heightmap. Is there any way to implement a base behavior in Mesh, but "change" the return type in the more derived class? I thought this was the purpose of covariance, but I can't seem to figure it out.
Please try the following code, it should work like charm. Replace the Methods/Exception to your own implementation.
public interface ITransformable<T, out S> where S : ITransformable<T, S>
{
S Slice(int x, int y, int width, int height);
S Slice(Rectangle value);
S Transpose();
S Flip(bool horizontal, bool vertical);
S Rotate(bool clockwise);
}
public class Mesh<T, S> : ITransformable<T, S> where S : Mesh<T,S>, ITransformable<T, S>, new()
{
public S Slice(int x, int y, int width, int height)
{
throw new NotImplementedException();
}
public S Slice(Rectangle value)
{
throw new NotImplementedException();
}
public S Transpose()
{
//The following will work smoothly.
S sObject = this.Slice(10, 20, 30, 40);
return sObject;
}
public S Flip(bool horizontal, bool vertical)
{
throw new NotImplementedException();
}
public S Rotate(bool clockwise)
{
throw new NotImplementedException();
}
}
public class Heightmap : Mesh<float, Heightmap>
{
}
public class Program
{
static void Main()
{
Heightmap heightmap = new Heightmap();
Heightmap map2 = heightmap.Transpose(); //This will work smoothly.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With