Last active
August 3, 2018 03:32
-
-
Save programmation/acd140048f7a3641d5609005868173b2 to your computer and use it in GitHub Desktop.
Framework defaults by Interface extensions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Drawing; | |
// adapted from https://stackoverflow.com/a/37980328 | |
namespace FrameworkInterface | |
{ | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
var model3 = new Tesla(new Robot() { Name = "Tesla" }); | |
model3.AddMoveHandler ((s, e) => { ReportPosition($"{e.Name} Event", e.Speed, e.Position); }); | |
model3.Move(42, 1, 1); | |
var googleCar = new GoogleCar(new Robot()); | |
googleCar.set_Name("GoogleCar"); | |
googleCar.AddMoveHandler((s, e) => { ReportPosition($"{e.Name} Event", e.Speed, e.Position); }); | |
googleCar.Move(20, 2, 3); | |
Console.WriteLine($"{model3.AutoName} Speed: {model3.AutoSpeed} Position {model3.AutoPosition}"); | |
Console.WriteLine($"{googleCar.get_Name()} Speed: {googleCar.get_Speed()} Position {googleCar.get_Position()}"); | |
Console.ReadLine(); | |
} | |
public static void ReportPosition(string robotName, double speed, PointF position) | |
{ | |
Console.WriteLine($"Robot: {robotName} Speed: {speed} Position {position}"); | |
} | |
} | |
public class MovedEventArgs : EventArgs | |
{ | |
public string Name { get; private set; } | |
public double Speed { get; private set; } | |
public PointF Position { get; private set; } | |
public MovedEventArgs(string name, double speed, PointF position) | |
{ | |
Name = name; | |
Speed = speed; | |
Position = position; | |
} | |
} | |
// Interface for the framework base class | |
public interface IRobot | |
{ | |
event EventHandler<MovedEventArgs> Moved; | |
string Name { get; set; } | |
double Speed { get; } | |
PointF Position { get; set; } | |
void Move(double milliseconds, float deltaX, float deltaY); | |
void Move(TimeSpan interval, float deltaX, float deltaY); | |
} | |
// Framework base class | |
public class Robot : IRobot | |
{ | |
public event EventHandler<MovedEventArgs> Moved; | |
public string Name { get; set; } | |
public double Speed { get; private set; } | |
public PointF Position { get; set; } | |
public void Move(double milliseconds, float deltaX, float deltaY) | |
{ | |
Move(TimeSpan.FromMilliseconds(milliseconds), deltaX, deltaY); | |
} | |
public void Move(TimeSpan interval, float deltaX, float deltaY) | |
{ | |
var position = Position; | |
Position = new PointF(Position.X + deltaX, Position.Y + deltaY); | |
Speed = Math.Sqrt(deltaX * deltaX + deltaY * deltaY) / interval.TotalMilliseconds; | |
Moved?.Invoke(this, new MovedEventArgs(Name, Speed, Position)); | |
} | |
} | |
// Interface to be injected into non-framework classes | |
public interface IRobotic | |
{ | |
IRobot Robot { get; } | |
} | |
// Default implementation of injected interface | |
public static class IRoboticHelper | |
{ | |
public static string get_Name(this IRobotic robotic) | |
=> robotic.Robot.Name; | |
public static string set_Name(this IRobotic robotic, string name) | |
=> robotic.Robot.Name = name; | |
public static double get_Speed(this IRobotic robotic) | |
=> robotic.Robot.Speed; | |
public static PointF get_Position(this IRobotic robotic) | |
=> robotic.Robot.Position; | |
public static void AddMoveHandler(this IRobotic robotic, EventHandler<MovedEventArgs> handler) | |
{ | |
robotic.Robot.Moved += handler; | |
} | |
public static void RemoveMoveHandler(this IRobotic robotic, EventHandler<MovedEventArgs> handler) | |
{ | |
robotic.Robot.Moved -= handler; | |
} | |
public static void Move(this IRobotic robotic, double milliseconds, float x, float y) | |
{ | |
robotic.Robot.Move(milliseconds, x, y); | |
} | |
public static void Move(this IRobotic robotic, TimeSpan interval, float x, float y) | |
{ | |
robotic.Robot.Move(interval, x, y); | |
} | |
} | |
// Non-framework base class | |
public abstract class Automaton : IRobotic | |
{ | |
public IRobot Robot { get; private set; } | |
public string AutoName => Robot?.Name; | |
public double AutoSpeed => Robot?.Speed ?? -1; | |
public PointF AutoPosition => Robot?.Position ?? PointF.Empty; | |
protected Automaton(IRobot robot) | |
{ | |
Robot = robot; | |
} | |
} | |
// Application class | |
public class Tesla : Automaton | |
{ | |
public Tesla(IRobot robot) : base(robot) | |
{ | |
} | |
} | |
// Application class | |
public class GoogleCar : Automaton | |
{ | |
public GoogleCar(IRobot robot) : base(robot) | |
{ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment