I came across an issue of wanting to have a function carry out any Action (or say Func) on any type within my domain.
Generally when I wanted to cut down on repeatable code using one class, say a Foo class, I’d follow this format:
private static void DoFoos() { DoFooAction(d => d.DoFoo()); DoFooAction(d => d.DoFooWithInput("Hello Foo World!")); } private static void DoFooAction(Action<IFoo> action) { IFoo foo = new Foo(); action(foo); } public class Foo : IFoo { public void DoFoo() { Console.WriteLine("Foo."); } public void DoFooWithInput(string input) { Console.WriteLine("Foo input: " + input); } }
This way, I could just use a lambda expression for any use of a Foo method that needed to be invoked.
What if instead, I want the same DoFooAction method to carry out the action of any Type?
In comes Generics and specifically Generics with constraints, and now I can use any other type, say a new type Moo:
private static void DoAllActions<T>(Action<T> action) where T : new() { action(new T()); }
public class Moo { public void DoMoo() { Console.WriteLine("Moo!"); } public void DoMooCalc(int a, int b) { var sum = a + b; Console.WriteLine("a + b = " + sum.ToString()); } }
The above Generic method can do both Moo and Foo with the appropriate Lambdas:
private static void DoMooandFoo() { DoAllActions<Foo>(d => d.DoFoo()); DoAllActions<Foo>(d => d.DoFooWithInput("hello.")); DoAllActions<Moo>(d => d.DoMoo()); DoAllActions<Moo>(d => d.DoMooCalc(1, 2)); }
Generics allow type safety at compile time and cut down even more on the amount of code needed in the past to carry out the same action but on different types.
