diff options
Diffstat (limited to 'csharp.html.markdown')
-rw-r--r-- | csharp.html.markdown | 353 |
1 files changed, 320 insertions, 33 deletions
diff --git a/csharp.html.markdown b/csharp.html.markdown index 442700a6..b965c2d4 100644 --- a/csharp.html.markdown +++ b/csharp.html.markdown @@ -14,20 +14,22 @@ filename: LearnCSharp.cs C# is an elegant and type-safe object-oriented language that enables developers to build a variety of secure and robust applications that run on the .NET Framework. -[Read more here.](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx) +[Read more here.](https://docs.microsoft.com/dotnet/csharp/getting-started/introduction-to-the-csharp-language-and-the-net-framework) ```c# // Single-line comments start with // + /* Multi-line comments look like this */ + /// <summary> /// This is an XML documentation comment which can be used to generate external /// documentation or provide context help within an IDE /// </summary> /// <param name="firstParam">This is some parameter documentation for firstParam</param> /// <returns>Information on the returned value of a function</returns> -//public void MethodOrClassOrOtherWithParsableHelp(string firstParam) {} +public void MethodOrClassOrOtherWithParsableHelp(string firstParam) {} // Specify the namespaces this source code will be using // The namespaces below are all part of the standard .NET Framework Class Library @@ -132,6 +134,12 @@ namespace Learning.CSharp DateTime fooDate = DateTime.Now; Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); + // Verbatim String + // You can use the @ symbol before a string literal to escape all characters in the string + string path = "C:\\Users\\User\\Desktop"; + string verbatimPath = @"C:\Users\User\Desktop"; + Console.WriteLine(path == verbatimPath); // => true + // You can split a string over two lines with the @ symbol. To escape " use "" string bazString = @"Here's some stuff on a new line! ""Wow!"", the masses cried"; @@ -248,7 +256,7 @@ on a new line! ""Wow!"", the masses cried"; int fooWhile = 0; while (fooWhile < 100) { - //Iterated 100 times, fooWhile 0->99 + // Iterated 100 times, fooWhile 0->99 fooWhile++; } @@ -267,10 +275,10 @@ on a new line! ""Wow!"", the masses cried"; } while (fooDoWhile < 100); - //for loop structure => for(<start_statement>; <conditional>; <step>) + // for loop structure => for(<start_statement>; <conditional>; <step>) for (int fooFor = 0; fooFor < 10; fooFor++) { - //Iterated 10 times, fooFor 0->9 + // Iterated 10 times, fooFor 0->9 } // For Each Loop @@ -281,7 +289,7 @@ on a new line! ""Wow!"", the masses cried"; // (The ToCharArray() could be removed, because a string also implements IEnumerable) foreach (char character in "Hello World".ToCharArray()) { - //Iterated over all the characters in the string + // Iterated over all the characters in the string } // Switch Case @@ -323,7 +331,7 @@ on a new line! ""Wow!"", the masses cried"; // Convert String To Integer // this will throw a FormatException on failure - int.Parse("123");//returns an integer version of "123" + int.Parse("123"); // returns an integer version of "123" // try parse will default to type default on failure // in this case: 0 @@ -338,7 +346,7 @@ on a new line! ""Wow!"", the masses cried"; tryInt.ToString(); // Casting - // Cast decimal 15 to a int + // Cast decimal 15 to an int // and then implicitly cast to long long x = (int) 15M; } @@ -367,7 +375,7 @@ on a new line! ""Wow!"", the masses cried"; Console.Read(); } // End main method - // CONSOLE ENTRY A console application must have a main method as an entry point + // CONSOLE ENTRY - A console application must have a main method as an entry point public static void Main(string[] args) { OtherInterestingFeatures(); @@ -398,7 +406,7 @@ on a new line! ""Wow!"", the masses cried"; ref int maxCount, // Pass by reference out int count) { - //the argument passed in as 'count' will hold the value of 15 outside of this function + // the argument passed in as 'count' will hold the value of 15 outside of this function count = 15; // out param must be assigned before control leaves the method } @@ -546,7 +554,7 @@ on a new line! ""Wow!"", the masses cried"; } // PARALLEL FRAMEWORK - // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx + // https://devblogs.microsoft.com/csharpfaq/parallel-programming-in-net-framework-4-getting-started/ var words = new List<string> {"dog", "cat", "horse", "pony"}; @@ -558,11 +566,11 @@ on a new line! ""Wow!"", the masses cried"; } ); - //Running this will produce different outputs - //since each thread finishes at different times. - //Some example outputs are: - //cat dog horse pony - //dog horse pony cat + // Running this will produce different outputs + // since each thread finishes at different times. + // Some example outputs are: + // cat dog horse pony + // dog horse pony cat // DYNAMIC OBJECTS (great for working with other languages) dynamic student = new ExpandoObject(); @@ -593,7 +601,7 @@ on a new line! ""Wow!"", the masses cried"; Console.WriteLine(bikeSummary.Name); // ASPARALLEL - // And this is where things get wicked - combines linq and parallel operations + // And this is where things get wicked - combine linq and parallel operations var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); // this will happen in parallel! Threads will automagically be spun up and the // results divvied amongst them! Amazing for large datasets when you have lots of @@ -613,7 +621,7 @@ on a new line! ""Wow!"", the masses cried"; .ThenBy(b => b.Name) .Select(b => b.Name); // still no query run - // Now the query runs, but opens a reader, so only populates are you iterate through + // Now the query runs, but opens a reader, so only populates as you iterate through foreach (string bike in query) Console.WriteLine(result); @@ -634,6 +642,54 @@ on a new line! ""Wow!"", the masses cried"; } } + + // DELEGATES AND EVENTS + public class DelegateTest + { + public static int count = 0; + public static int Increment() + { + // increment count then return it + return ++count; + } + + // A delegate is a reference to a method. + // To reference the Increment method, + // first declare a delegate with the same signature, + // i.e. takes no arguments and returns an int + public delegate int IncrementDelegate(); + + // An event can also be used to trigger delegates + // Create an event with the delegate type + public static event IncrementDelegate MyEvent; + + static void Main(string[] args) + { + // Refer to the Increment method by instantiating the delegate + // and passing the method itself in as an argument + IncrementDelegate inc = new IncrementDelegate(Increment); + Console.WriteLine(inc()); // => 1 + + // Delegates can be composed with the + operator + IncrementDelegate composedInc = inc; + composedInc += inc; + composedInc += inc; + + // composedInc will run Increment 3 times + Console.WriteLine(composedInc()); // => 4 + + + // Subscribe to the event with the delegate + MyEvent += new IncrementDelegate(Increment); + MyEvent += new IncrementDelegate(Increment); + + // Trigger the event + // ie. run all delegates subscribed to this event + Console.WriteLine(MyEvent()); // => 6 + } + } + + // Class Declaration Syntax: // <public/private/protected/internal> class <class name>{ // //data fields, constructors, functions all inside. @@ -671,10 +727,10 @@ on a new line! ""Wow!"", the masses cried"; int _speed; // Everything is private by default: Only accessible from within this class. // can also use keyword private public string Name { get; set; } - + // Properties also have a special syntax for when you want a readonly property // that simply returns the result of an expression - public string LongName => Name + " " + _speed + " speed"; + public string LongName => Name + " " + _speed + " speed"; // Enum is a value type that consists of a set of named constants // It is really just mapping a name to a value (an int, unless specified otherwise). @@ -711,7 +767,7 @@ on a new line! ""Wow!"", the masses cried"; // Before .NET 4: (aBike.Accessories & Bicycle.BikeAccessories.Bell) == Bicycle.BikeAccessories.Bell public BikeAccessories Accessories { get; set; } - // Static members belong to the type itself rather then specific object. + // Static members belong to the type itself rather than specific object. // You can access them without a reference to any object: // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated); public static int BicyclesCreated { get; set; } @@ -811,7 +867,7 @@ on a new line! ""Wow!"", the masses cried"; } } - //Method to display the attribute values of this Object. + // Method to display the attribute values of this Object. public virtual string Info() { return "Gear: " + Gear + @@ -906,7 +962,7 @@ on a new line! ""Wow!"", the masses cried"; /// <summary> /// Used to connect to DB for LinqToSql example. /// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional) - /// http://msdn.microsoft.com/en-us/data/jj193542.aspx + /// https://docs.microsoft.com/ef/ef6/modeling/code-first/workflows/new-database /// </summary> public class BikeRepository : DbContext { @@ -949,6 +1005,7 @@ on a new line! ""Wow!"", the masses cried"; // String interpolation by prefixing the string with $ // and wrapping the expression you want to interpolate with { braces } + // You can also combine both interpolated and verbatim strings with $@ public class Rectangle { public int Length { get; set; } @@ -961,6 +1018,9 @@ on a new line! ""Wow!"", the masses cried"; { Rectangle rect = new Rectangle { Length = 5, Width = 3 }; Console.WriteLine($"The length is {rect.Length} and the width is {rect.Width}"); + + string username = "User"; + Console.WriteLine($@"C:\Users\{username}\Desktop"); } } @@ -1006,15 +1066,242 @@ on a new line! ""Wow!"", the masses cried"; // x?.y will return null immediately if x is null; y is not evaluated => GenieName?.ToUpper(); } + + static class MagicService + { + private static bool LogException(Exception ex) + { + // log exception somewhere + return false; + } + + public static bool CastSpell(string spell) + { + try + { + // Pretend we call API here + throw new MagicServiceException("Spell failed", 42); + + // Spell succeeded + return true; + } + // Only catch if Code is 42 i.e. spell failed + catch(MagicServiceException ex) when (ex.Code == 42) + { + // Spell failed + return false; + } + // Other exceptions, or MagicServiceException where Code is not 42 + catch(Exception ex) when (LogException(ex)) + { + // Execution never reaches this block + // The stack is not unwound + } + return false; + // Note that catching a MagicServiceException and rethrowing if Code + // is not 42 or 117 is different, as then the final catch-all block + // will not catch the rethrown exception + } + } + + public class MagicServiceException : Exception + { + public int Code { get; } + + public MagicServiceException(string message, int code) : base(message) + { + Code = code; + } + } + + public static class PragmaWarning { + // Obsolete attribute + [Obsolete("Use NewMethod instead", false)] + public static void ObsoleteMethod() + { + // obsolete code + } + + public static void NewMethod() + { + // new code + } + + public static void Main() + { + ObsoleteMethod(); // CS0618: 'ObsoleteMethod is obsolete: Use NewMethod instead' +#pragma warning disable CS0618 + ObsoleteMethod(); // no warning +#pragma warning restore CS0618 + ObsoleteMethod(); // CS0618: 'ObsoleteMethod is obsolete: Use NewMethod instead' + } + } } // End Namespace + +using System; +// C# 6, static using +using static System.Math; + +namespace Learning.More.CSharp +{ + class StaticUsing + { + static void Main() + { + // Without a static using statement.. + Console.WriteLine("The square root of 4 is {}.", Math.Sqrt(4)); + // With one + Console.WriteLine("The square root of 4 is {}.", Sqrt(4)); + } + } +} + +// New C# 7 Feature +// Install Microsoft.Net.Compilers Latest from Nuget +// Install System.ValueTuple Latest from Nuget +using System; +namespace Csharp7 +{ + // TUPLES, DECONSTRUCTION AND DISCARDS + class TuplesTest + { + public (string, string) GetName() + { + // Fields in tuples are by default named Item1, Item2... + var names1 = ("Peter", "Parker"); + Console.WriteLine(names1.Item2); // => Parker + + // Fields can instead be explicitly named + // Type 1 Declaration + (string FirstName, string LastName) names2 = ("Peter", "Parker"); + + // Type 2 Declaration + var names3 = (First:"Peter", Last:"Parker"); + + Console.WriteLine(names2.FirstName); // => Peter + Console.WriteLine(names3.Last); // => Parker + + return names3; + } + + public string GetLastName() { + var fullName = GetName(); + + // Tuples can be deconstructed + (string firstName, string lastName) = fullName; + + // Fields in a deconstructed tuple can be discarded by using _ + var (_, last) = fullName; + return last; + } + + // Any type can be deconstructed in the same way by + // specifying a Deconstruct method + public int randomNumber = 4; + public int anotherRandomNumber = 10; + + public void Deconstruct(out int randomNumber, out int anotherRandomNumber) + { + randomNumber = this.randomNumber; + anotherRandomNumber = this.anotherRandomNumber; + } + + static void Main(string[] args) + { + var tt = new TuplesTest(); + (int num1, int num2) = tt; + Console.WriteLine($"num1: {num1}, num2: {num2}"); // => num1: 4, num2: 10 + + Console.WriteLine(tt.GetLastName()); + } + } + + // PATTERN MATCHING + class PatternMatchingTest + { + public static (string, int)? CreateLogMessage(object data) + { + switch(data) + { + // Additional filtering using when + case System.Net.Http.HttpRequestException h when h.Message.Contains("404"): + return (h.Message, 404); + case System.Net.Http.HttpRequestException h when h.Message.Contains("400"): + return (h.Message, 400); + case Exception e: + return (e.Message, 500); + case string s: + return (s, s.Contains("Error") ? 500 : 200); + case null: + return null; + default: + return (data.ToString(), 500); + } + } + } + + // REFERENCE LOCALS + // Allow you to return a reference to an object instead of just its value + class RefLocalsTest + { + // note ref in return + public static ref string FindItem(string[] arr, string el) + { + for(int i=0; i<arr.Length; i++) + { + if(arr[i] == el) { + // return the reference + return ref arr[i]; + } + } + throw new Exception("Item not found"); + } + + public static void SomeMethod() + { + string[] arr = {"this", "is", "an", "array"}; + + // note refs everywhere + ref string item = ref FindItem(arr, "array"); + item = "apple"; + Console.WriteLine(arr[3]); // => apple + } + } + + // LOCAL FUNCTIONS + class LocalFunctionTest + { + private static int _id = 0; + public int id; + public LocalFunctionTest() + { + id = generateId(); + + // This local function can only be accessed in this scope + int generateId() + { + return _id++; + } + } + + public static void AnotherMethod() + { + var lf1 = new LocalFunctionTest(); + var lf2 = new LocalFunctionTest(); + Console.WriteLine($"{lf1.id}, {lf2.id}"); // => 0, 1 + + int id = generateId(); + // error CS0103: The name 'generateId' does not exist in the current context + } + } +} + ``` ## Topics Not Covered * Attributes - * async/await, pragma directives - * Exception filters - * `using static` + * async/await * Web Development * ASP.NET MVC & WebApi (new) * ASP.NET Web Forms (old) @@ -1025,13 +1312,13 @@ on a new line! ""Wow!"", the masses cried"; ## Further Reading + * [C# language reference](https://docs.microsoft.com/dotnet/csharp/language-reference/) + * [Learn .NET](https://dotnet.microsoft.com/learn) + * [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions) * [DotNetPerls](http://www.dotnetperls.com) * [C# in Depth](http://manning.com/skeet2) - * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) - * [LINQ](http://shop.oreilly.com/product/9780596519254.do) - * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) - * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) - * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials) - * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) + * [Programming C# 5.0](http://shop.oreilly.com/product/0636920024064.do) + * [LINQ Pocket Reference](http://shop.oreilly.com/product/9780596519254.do) * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) - * [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx) + * [freeCodeCamp - C# Tutorial for Beginners](https://www.youtube.com/watch?v=GhQdlIFylQ8) +
\ No newline at end of file |