Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// <summary>
- /// This is an example of how to implement a Mixin pattern in C# with the help of interfaces, extension methods, and
- /// generics.
- /// </summary>
- using System;
- using RectangleMixin;
- using MovableMixin;
- using PlottableMixin;
- using Example;
- /// <summary>
- /// Simple no generics approach to mixins
- /// </summary>
- namespace PlottableMixin
- {
- /// <summary>
- /// Setup interface member constraints necessary for the mixin functionality.
- /// </summary>
- public interface IPlottable
- {
- Coordinates coordinates { get; set; }
- int Width { get; set; }
- int Height { get; set; }
- }
- /// <summary>
- /// Uses Extension Methods to populate this interface with built in functionality
- /// </summary>
- public static class IPlottableExtensions
- {
- public static Coordinates GetCenterCoordinates(this IPlottable obj)
- {
- return new Coordinates() {
- X = obj.coordinates.X + obj.Width/2,
- Y = obj.coordinates.Y + obj.Height/2
- };
- }
- public static Coordinates GetMaxCoordinates(this IPlottable obj)
- {
- return new Coordinates()
- {
- X = obj.coordinates.X + obj.Width,
- Y = obj.coordinates.Y + obj.Height
- };
- }
- public static int GetMaxX(this IPlottable obj)
- {
- return obj.coordinates.X + obj.Width;
- }
- public static int GetMaxY(this IPlottable obj)
- {
- return obj.coordinates.Y + obj.Height;
- }
- }
- }
- namespace MovableMixin
- {
- /// <summary>
- /// The interface is generic so that the mixin functions can be chainable by returning type T.
- /// </summary>
- public interface IMovable<T>
- {
- Coordinates coordinates { get; set; }
- }
- public static class IMovableExtensions
- {
- public static T Move<T>(this T movable, int x, int y)
- where T: IMovable<T>
- {
- movable.coordinates.X += x;
- movable.coordinates.Y += y;
- return movable;
- }
- }
- }
- namespace RectangleMixin
- {
- public interface IRectangle<T>
- {
- int Width { get; set; }
- int Height { get; set; }
- }
- public static class IRectangleExtensions
- {
- // Note: Since GetArea isn't meant to be chainable (returns its own value) it can extend IRectangle<T> directly
- // without having to extend a type T that is constrained by 'where T: IRectangle<T>'.
- public static int GetArea<T>(this IRectangle<T> rect)
- {
- return rect.Width * rect.Height;
- }
- public static T Shrink<T>(this T rect, int amount)
- where T: IRectangle<T>
- {
- rect.Width -= amount;
- rect.Height -= amount;
- return rect;
- }
- public static T Shrink<T>(this T rect, int width, int height)
- where T: IRectangle<T>
- {
- rect.Width -= width;
- rect.Height -= height;
- return rect;
- }
- public static T Grow<T>(this T rect, int amount)
- where T: IRectangle<T>
- {
- rect.Width += amount;
- rect.Height += amount;
- return rect;
- }
- public static T Grow<T>(this T rect, int width, int height)
- where T:IRectangle<T>
- {
- rect.Width += width;
- rect.Height += height;
- return rect;
- }
- }
- }
- namespace Example
- {
- public class Button : IRectangle<Button>, IMovable<Button>, IPlottable
- {
- public int Width { get; set; }
- public int Height { get; set; }
- public Coordinates coordinates { get; set; }
- public string Label { get; set; }
- public Button(int x, int y, int width, int height)
- {
- this.coordinates = new Coordinates() {
- X = x,
- Y = y
- };
- this.Width = width;
- this.Height = height;
- }
- public override string ToString()
- {
- return string.Format(
- "\n\tArea: {0}, \n\tWidth: {1}, \n\tHeight: {2}, \n\tCoordinates: {3}, \n\tMax Coordinates {4}, \n\tCenter Coordinates: {5}",
- this.GetArea(),
- Width,
- Height,
- coordinates,
- this.GetMaxCoordinates(),
- this.GetCenterCoordinates()
- );
- }
- }
- public class Coordinates
- {
- public int X;
- public int Y;
- public override string ToString()
- {
- return string.Format("(X: {0}, Y: {1})", X, Y);
- }
- }
- class MainClass
- {
- public static void Main (string[] args)
- {
- var btn = new Button(0, 0, 100, 25);
- Console.WriteLine("New Button: {0}\n", btn);
- Console.WriteLine("Shrunk Button: {0}\n", btn.Shrink(20,0));
- Console.WriteLine("Move Button: {0}\n", btn.Move(20,20));
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment