Interface with basic implementation in C#
Today we have simple question:
How to avoid abstract classes by giving base implementation?
The story
Once in a time I was building animation system which was planned to be used in IGWOCTISI project. It happened that I wanted to created some predefined tweens (animated translations) like ScaleTo, MoveTo, RotateBy and so on.
In the horizon appeared a requirement which was pretty straightforward:
public class MoveTo<T> : Animation<T>
where T : ITransformable
The fact was that my type T not always was able to be some Transformable object.
1st level - abstract class
You may already noticed it. This approach was not good enough. I could add some properties and non-static methods. But there were classes where I would have to extend from two abstract classes, which is not possible in C#.
abstract class Transformable
{
private float x, y, z;
}
2nd level - use interface!
So why not try with interfaces? Basic multi-language approach.
Yeah. I have only some methods which I would have to implement as static but it’s not abstract. But I can mimic variables by getters/setters.
interface ITransformable {
float X { get; set; }
float Y { get; set; }
float Z { get; set; }
}
3rd level - use Extension Methods!
Use interface! and extension methods.
Extension Methods is a technique to provide methods like they were given in abstract classes (non-static) but can be applied to any other chosen class or interface.
Implementation example
public static class ITransformableExtensions {
public static Matrix CalculateWorldTransform(this ITransformable t) {
return t.Rotation
* Matrix.CreateScale(t.ScaleX, t.ScaleY, t.ScaleZ)
* Matrix.CreateTranslation(t.X, t.Y, t.Z);
}
}
Use example
ITransformable spaceship = getSomeSpaceship();
var matrix = spaceship.CalculateWorldTransform(); //profit!
More on this topic on official page: http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx
Pros and cons
Not much to say. It’s not easy to port such code to Java or other OOP languages. So if you plan such move I suggest to not use Extension Methods.