summaryrefslogtreecommitdiffhomepage
path: root/csharp.html.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'csharp.html.markdown')
-rw-r--r--csharp.html.markdown353
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