Guest User

nxn

a guest
Jun 4th, 2011
420
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.31 KB | None | 0 0
  1. /// <summary>
  2. /// This is an example of how to implement a Mixin pattern in C# with the help of interfaces, extension methods, and
  3. /// generics.
  4. /// </summary>
  5.  
  6. using System;
  7. using RectangleMixin;
  8. using MovableMixin;
  9. using PlottableMixin;
  10. using Example;
  11.  
  12. /// <summary>
  13. /// Simple no generics approach to mixins
  14. /// </summary>
  15. namespace PlottableMixin
  16. {
  17.     /// <summary>
  18.     /// Setup interface member constraints necessary for the mixin functionality.
  19.     /// </summary>
  20.     public interface IPlottable
  21.     {
  22.         Coordinates coordinates { get; set; }
  23.         int Width { get; set; }
  24.         int Height { get; set; }
  25.     }
  26.    
  27.     /// <summary>
  28.     /// Uses Extension Methods to populate this interface with built in functionality
  29.     /// </summary>
  30.     public static class IPlottableExtensions
  31.     {
  32.         public static Coordinates GetCenterCoordinates(this IPlottable obj)
  33.         {
  34.             return new Coordinates() {
  35.                 X = obj.coordinates.X + obj.Width/2,
  36.                 Y = obj.coordinates.Y + obj.Height/2
  37.             };
  38.         }
  39.        
  40.         public static Coordinates GetMaxCoordinates(this IPlottable obj)
  41.         {
  42.             return new Coordinates()
  43.             {
  44.                 X = obj.coordinates.X + obj.Width,
  45.                 Y = obj.coordinates.Y + obj.Height
  46.             };
  47.         }
  48.        
  49.         public static int GetMaxX(this IPlottable obj)
  50.         {
  51.             return obj.coordinates.X + obj.Width;
  52.         }
  53.        
  54.         public static int GetMaxY(this IPlottable obj)
  55.         {
  56.             return obj.coordinates.Y + obj.Height;
  57.         }
  58.     }
  59. }
  60.  
  61. namespace MovableMixin
  62. {
  63.     /// <summary>
  64.     /// The interface is generic so that the mixin functions can be chainable by returning type T.
  65.     /// </summary>
  66.     public interface IMovable<T>
  67.     {
  68.         Coordinates coordinates { get; set; }
  69.     }
  70.    
  71.     public static class IMovableExtensions
  72.     {
  73.         public static T Move<T>(this T movable, int x, int y)
  74.         where T: IMovable<T>
  75.         {
  76.             movable.coordinates.X += x;
  77.             movable.coordinates.Y += y;
  78.             return movable;
  79.         }
  80.     }
  81. }
  82.  
  83.  
  84. namespace RectangleMixin
  85. {
  86.  
  87.     public interface IRectangle<T>
  88.     {
  89.         int Width { get; set; }
  90.         int Height { get; set; }
  91.     }
  92.    
  93.     public static class IRectangleExtensions
  94.     {
  95.         // Note: Since GetArea isn't meant to be chainable (returns its own value) it can extend IRectangle<T> directly
  96.         // without having to extend a type T that is constrained by 'where T: IRectangle<T>'.
  97.         public static int GetArea<T>(this IRectangle<T> rect)
  98.         {
  99.             return rect.Width * rect.Height;
  100.         }
  101.        
  102.         public static T Shrink<T>(this T rect, int amount)
  103.         where T: IRectangle<T>
  104.         {
  105.             rect.Width -= amount;
  106.             rect.Height -= amount;
  107.             return rect;
  108.         }
  109.        
  110.         public static T Shrink<T>(this T rect, int width, int height)
  111.         where T: IRectangle<T>
  112.         {
  113.             rect.Width -= width;
  114.             rect.Height -= height;
  115.             return rect;
  116.         }
  117.        
  118.         public static T Grow<T>(this T rect, int amount)
  119.         where T: IRectangle<T>
  120.         {
  121.             rect.Width += amount;
  122.             rect.Height += amount;
  123.             return rect;
  124.         }
  125.        
  126.         public static T Grow<T>(this T rect, int width, int height)
  127.         where T:IRectangle<T>
  128.         {
  129.             rect.Width += width;
  130.             rect.Height += height;
  131.             return rect;
  132.         }
  133.     }
  134. }
  135.  
  136. namespace Example
  137. {
  138.     public class Button : IRectangle<Button>, IMovable<Button>, IPlottable
  139.     {
  140.         public int Width { get; set; }
  141.         public int Height { get; set; }
  142.         public Coordinates coordinates { get; set; }
  143.        
  144.         public string Label { get; set; }
  145.        
  146.         public Button(int x, int y, int width, int height)
  147.         {
  148.             this.coordinates = new Coordinates() {
  149.                 X = x,
  150.                 Y = y
  151.             };
  152.             this.Width = width;
  153.             this.Height = height;
  154.         }
  155.        
  156.         public override string ToString()
  157.         {
  158.             return string.Format(
  159.                 "\n\tArea: {0}, \n\tWidth: {1}, \n\tHeight: {2}, \n\tCoordinates: {3}, \n\tMax Coordinates {4}, \n\tCenter Coordinates: {5}",
  160.                  this.GetArea(),
  161.                  Width,
  162.                  Height,
  163.                  coordinates,
  164.                  this.GetMaxCoordinates(),
  165.                  this.GetCenterCoordinates()
  166.             );
  167.         }
  168.     }
  169.    
  170.     public class Coordinates
  171.     {
  172.         public int X;
  173.         public int Y;
  174.        
  175.         public override string ToString()
  176.         {
  177.             return string.Format("(X: {0}, Y: {1})", X, Y);
  178.         }
  179.     }
  180.    
  181.     class MainClass
  182.     {
  183.         public static void Main (string[] args)
  184.         {
  185.             var btn = new Button(0, 0, 100, 25);
  186.            
  187.             Console.WriteLine("New Button: {0}\n", btn);
  188.             Console.WriteLine("Shrunk Button: {0}\n", btn.Shrink(20,0));
  189.             Console.WriteLine("Move Button: {0}\n", btn.Move(20,20));
  190.         }
  191.     }
  192. }
Advertisement
Add Comment
Please, Sign In to add comment