diff --git a/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas.sln b/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas.sln
new file mode 100644
index 0000000..6827928
--- /dev/null
+++ b/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2010
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DelegatesMethodsLambdas", "DelegatesMethodsLambdas\DelegatesMethodsLambdas.csproj", "{0C729953-CE58-45C0-B24D-5F0F5A45E717}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0C729953-CE58-45C0-B24D-5F0F5A45E717}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0C729953-CE58-45C0-B24D-5F0F5A45E717}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0C729953-CE58-45C0-B24D-5F0F5A45E717}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0C729953-CE58-45C0-B24D-5F0F5A45E717}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {2D4AEE57-5985-4029-8026-F5680B37D5C3}
+ EndGlobalSection
+EndGlobal
diff --git a/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas/DelegatesMethodsLambdas.csproj b/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas/DelegatesMethodsLambdas.csproj
new file mode 100644
index 0000000..ce1697a
--- /dev/null
+++ b/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas/DelegatesMethodsLambdas.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ netcoreapp2.0
+
+
+
diff --git a/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas/Program.cs b/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas/Program.cs
new file mode 100644
index 0000000..5bc9356
--- /dev/null
+++ b/C# General/DelegatesMethodsLambdas/DelegatesMethodsLambdas/Program.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+
+namespace DelegatesMethodsLambdas
+{
+ class Program
+ {
+ // Defines a method that returns an int, and has one int as an input
+ // Delegate defines the signature (return type and parameters)
+ public delegate int Manipulate(int a);
+
+ // Action is just a delegate
+ public delegate void MyAction();
+
+ // Func is just a delegate with a return type
+ public delegate int MyFunc();
+
+ static void Main(string[] args)
+ {
+ // Invoking a normal method
+ var normalMethodInvokeResult = NormalMethod(2);
+
+ // Create an instance of the delegate
+ var normalMethodDelegate = new Manipulate(NormalMethod);
+ var normalResult = normalMethodDelegate(3);
+
+ // Pass a delegate method as a variable
+ var anotherResult = RunAnotherMethod(normalMethodDelegate, 4);
+
+ // Anonymous method is a a delegate() { } and it returns a delegate
+ Manipulate anonymousMethodDelegate = delegate (int a) { return a * 2; };
+ var anonymousResult = anonymousMethodDelegate(3);
+
+ // Lambda expressions are anything with => and a left/right value
+ // They can return a delegate (so a method that can be invoked)
+ // or an Expression of a delegate (so it can be compiled and then executed)
+ Manipulate lambaDelegate = a => a * 2;
+ var lambaResult = lambaDelegate(5);
+
+ // Nicer way to write a lamba
+ Manipulate nicerLambaDelegate = (a) => { return a * 2; };
+ var nicerLambaResult = nicerLambaDelegate(6);
+
+ // Lamba can return an Expression
+ Expression expressionLambda = a => a * 2;
+
+ // An Action is just a delegate with no return type and optional input
+ Action actionDelegate = () => { lambaDelegate(2); };
+ Action action2Delegate = (a) => { var b = a * 2; };
+
+ // A Func is just a delegate with a return type
+ Func myFunc = () => 2;
+
+ // Replace Manipulate with a Func
+ Func funcDelegate = a => a * 2;
+ var funcResult = funcDelegate(5);
+
+ // Mimic the FirstOrDefault Linq expression
+ var items = new List(new[] { "a", "b", "c", "d", "e", "f", "g"});
+ var itemInts = Enumerable.Range(1, 10).ToList();
+
+ // Calling the nuilt in Linq FirstOrDefault
+ var foundItem = items.FirstOrDefault(item => item == "c");
+
+ // Calling our version
+ var foundItem2 = items.GetFirstOrDefault(item => item == "c");
+ var foundItem3 = itemInts.GetFirstOrDefault(item => item > 4);
+ }
+
+ ///
+ /// A normal looking method
+ ///
+ /// The input value
+ /// Returns twice the input value
+ public static int NormalMethod(int a)
+ {
+ return a * 2;
+ }
+
+ ///
+ /// Accept a method (delegate) as an input
+ ///
+ ///
+ ///
+ ///
+ public static int RunAnotherMethod(Manipulate theMethod, int a)
+ {
+ return theMethod(a);
+ }
+ }
+
+ ///
+ /// Helpers classes
+ ///
+ public static class Helpers
+ {
+ ///
+ /// Mimic the behaviour of the FirstOrDefault Linq expression
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static TResult GetFirstOrDefault(this List items, Func findMatch)
+ {
+ // Loop each item
+ foreach (var item in items)
+ {
+ // See if caller method has found a match
+ if (findMatch(item))
+ // If so return it
+ return item;
+ }
+
+ // If there was no match, return default value of return type
+ return default(TResult);
+ }
+ }
+}