From 0cee5bd79af4deefe246dde09cdfcd44dca80558 Mon Sep 17 00:00:00 2001 From: Shaun McCarthy Date: Sat, 26 Oct 2013 14:34:39 -0400 Subject: Added Interesting Features (and fixed / cleaned up other code) Fixed syntax errors, made items more succinct, and added a section of interesting features in c# --- csharp.html.markdown | 583 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 354 insertions(+), 229 deletions(-) diff --git a/csharp.html.markdown b/csharp.html.markdown index 1471b833..f4c30b03 100644 --- a/csharp.html.markdown +++ b/csharp.html.markdown @@ -3,8 +3,8 @@ language: c# contributors: - ["Irfan Charania", "https://github.com/irfancharania"] - ["Max Yankov", "https://github.com/golergka"] - - ["Melvyn Laïly", "http://x2a.yt"] -filename: LearnCSharp.cs + - ["Melvyn Laïly", "http://x2a.yt"] + - ["Shaun McCarthy", "http://www.shaunmccarthy.com"] --- 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. @@ -23,7 +23,12 @@ Multi-line comments look like this // Specify namespaces application will be using using System; using System.Collections.Generic; - +using System.Data.Entity; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Net; +using System.Threading.Tasks; // defines scope to organize code into "packages" namespace Learning @@ -32,8 +37,8 @@ namespace Learning // you're allowed to do otherwise, but shouldn't for sanity. public class LearnCSharp { - // A console application must have a main method as an entry point - public static void Main(string[] args) + // BASIC SYNTAX - skip to INTERESTING FEATURES if you have used Java or C++ before + public static void Syntax() { // Use Console.WriteLine to print lines Console.WriteLine("Hello World"); @@ -46,7 +51,6 @@ namespace Learning Console.Write("Hello "); Console.Write("World"); - /////////////////////////////////////////////////// // Types & Variables // @@ -61,140 +65,83 @@ namespace Learning // (0 <= byte <= 255) byte fooByte = 100; - // Short - Signed 16-bit integer - // (-32,768 <= short <= 32,767) + // Short - 16-bit integer + // Signed - (-32,768 <= short <= 32,767) + // Unsigned - (0 <= ushort <= 65,535) short fooShort = 10000; - - // Ushort - Unsigned 16-bit integer - // (0 <= ushort <= 65,535) ushort fooUshort = 10000; - // Integer - Signed 32-bit integer - // (-2,147,483,648 <= int <= 2,147,483,647) - int fooInt = 1; + // Integer - 32-bit integer + int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647) + uint fooUint = 1; // (0 <= uint <= 4,294,967,295) - // Uinteger - Unsigned 32-bit integer - // (0 <= uint <= 4,294,967,295) - uint fooUint = 1; - - // Long - Signed 64-bit integer - // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) - long fooLong = 100000L; + // Long - 64-bit integer + long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615) + // Numbers default to being int or uint depending on size. // L is used to denote that this variable value is of type long or ulong - // anything without is treated as int or uint depending on size. - // Ulong - Unsigned 64-bit integer - // (0 <= ulong <= 18,446,744,073,709,551,615) - ulong fooUlong = 100000L; + // Double - Double-precision 64-bit IEEE 754 Floating Point + double fooDouble = 123.4; // Precision: 15-16 digits // Float - Single-precision 32-bit IEEE 754 Floating Point - // Precision: 7 digits - float fooFloat = 234.5f; - // f is used to denote that this variable value is of type float; - // otherwise it is treated as double. + float fooFloat = 234.5f; // Precision: 7 digits + // f is used to denote that this variable value is of type float - // Double - Double-precision 64-bit IEEE 754 Floating Point - // Precision: 15-16 digits - double fooDouble = 123.4; - - // Decimal - a 128-bits data type, with more precision than other floating-point types, - // suited for financial and monetary calculations - decimal fooDecimal = 150.3m; + // Decimal - a 128-bits data type, with more precision than other floating-point types, + // suited for financial and monetary calculations + decimal fooDecimal = 150.3m; // Boolean - true & false - bool fooBoolean = true; - bool barBoolean = false; + bool fooBoolean = true; // or false // Char - A single 16-bit Unicode character char fooChar = 'A'; // Strings -- unlike the previous base types which are all value types, - // a string is a reference type. That is, you can set it to null - string fooString = "My string is here!"; + // a string is a reference type. That is, you can set it to null + string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)"; Console.WriteLine(fooString); - // You can access each character of the string with an indexer: - char charFromString = fooString[1]; // 'y' - // Strings are immutable: you can't do fooString[1] = 'X'; - // formatting + // You can access each character of the string with an indexer: + char charFromString = fooString[1]; // 'y' + // Strings are immutable: you can't do fooString[1] = 'X'; + + // Compare strings with current culture, ignoring case + string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); + + // Formatting, based on sprintf string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2); - Console.WriteLine(fooFormattedString); - // formatting dates + // Dates & Formatting DateTime fooDate = DateTime.Now; Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); - // \n is an escaped character that starts a new line - string barString = "Printing on a new line?\nNo Problem!"; - Console.WriteLine(barString); - - // it can be written prettier by using the @ symbol + // You can split a string over two lines with the @ symbol. To escape " use "" string bazString = @"Here's some stuff - on a new line!"; - Console.WriteLine(bazString); - - // quotes need to be escaped - // use \" normally - string quotedString = "some \"quoted\" stuff"; - Console.WriteLine(quotedString); - - // use "" when strings start with @ - string quotedString2 = @"some MORE ""quoted"" stuff"; - Console.WriteLine(quotedString2); +on a new line! ""Wow!"", the masses cried"; // Use const or read-only to make a variable immutable // const values are calculated at compile time const int HOURS_I_WORK_PER_WEEK = 9001; - // Nullable types - // any value type (i.e. not a class) can be made nullable by suffixing a ? - // ? = - int? nullable = null; - Console.WriteLine("Nullable variable: " + nullable); - - // In order to use nullable's value, you have to use Value property - // or to explicitly cast it - DateTime? nullableDate = null; - // The previous line would not have compiled without the '?' - // because DateTime is a value type - // ? is equivalent to writing Nullable - Nullable otherNullableDate = nullableDate; - - nullableDate = DateTime.Now; - Console.WriteLine("Nullable value is: " + nullableDate.Value + " or: " + (DateTime) nullableDate ); - - // ?? is syntactic sugar for specifying default value - // in case variable is null - int notNullable = nullable ?? 0; - Console.WriteLine("Not nullable variable: " + notNullable); - - // Var - compiler will choose the most appropriate type based on value - // Please note that this does not remove type safety. - // In this case, the type of fooImplicit is known to be a bool at compile time - var fooImplicit = true; - /////////////////////////////////////////////////// // Data Structures /////////////////////////////////////////////////// - Console.WriteLine("\n->Data Structures"); - // Arrays + // Arrays - zero indexed // The array size must be decided upon declaration // The format for declaring an array is follows: // [] = new []; int[] intArray = new int[10]; - string[] stringArray = new string[1]; - bool[] boolArray = new bool[100]; // Another way to declare & initialize an array int[] y = { 9000, 1000, 1337 }; // Indexing an array - Accessing an element Console.WriteLine("intArray @ 0: " + intArray[0]); - - // Arrays are zero-indexed and mutable. + // Arrays are mutable. intArray[1] = 1; - Console.WriteLine("intArray @ 1: " + intArray[1]); // => 1 // Lists // Lists are used more frequently than arrays as they are more flexible @@ -202,28 +149,21 @@ namespace Learning // List = new List(); List intList = new List(); List stringList = new List(); - - // Another way to declare & initialize a list - List z = new List { 9000, 1000, 1337 }; - - // Indexing a list - Accessing an element - // Lists are zero-indexed and mutable. - Console.WriteLine("z @ 0: " + z[2]); + List z = new List { 9000, 1000, 1337 }; // intialize + // The <> are for templates - Check out the cool stuff section // Lists don't default to a value; // A value must be added before accessing the index intList.Add(1); Console.WriteLine("intList @ 0: " + intList[0]); - // Others data structures to check out: - // // Stack/Queue // Dictionary (an implementation of a hash map) + // HashSet // Read-only Collections // Tuple (.Net 4+) - /////////////////////////////////////// // Operators /////////////////////////////////////// @@ -232,10 +172,7 @@ namespace Learning int i1 = 1, i2 = 2; // Shorthand for multiple declarations // Arithmetic is straightforward - Console.WriteLine("1+2 = " + (i1 + i2)); // => 3 - Console.WriteLine("2-1 = " + (i2 - i1)); // => 1 - Console.WriteLine("2*1 = " + (i2 * i1)); // => 2 - Console.WriteLine("1/2 = " + (i1 / i2)); // => 0 (0.5 truncated down) + Console.WriteLine(i1 + i2 - i1 * 3 / 7); // // Modulo Console.WriteLine("11%3 = " + (11 % 3)); // => 2 @@ -266,7 +203,6 @@ namespace Learning Console.WriteLine(i--); //i = 1. Post-Decrementation Console.WriteLine(--i); //i = 0. Pre-Decrementation - /////////////////////////////////////// // Control Structures /////////////////////////////////////// @@ -291,50 +227,37 @@ namespace Learning // A simple if/else can be written as follows // ? : string isTrue = (true) ? "True" : "False"; - Console.WriteLine("Ternary demo: " + isTrue); - // While loop int fooWhile = 0; while (fooWhile < 100) { - //Console.WriteLine(fooWhile); - //Increment the counter //Iterated 99 times, fooWhile 0->99 fooWhile++; } - Console.WriteLine("fooWhile Value: " + fooWhile); // Do While Loop int fooDoWhile = 0; do { - //Console.WriteLine(fooDoWhile); - //Increment the counter //Iterated 99 times, fooDoWhile 0->99 fooDoWhile++; } while (fooDoWhile < 100); - Console.WriteLine("fooDoWhile Value: " + fooDoWhile); - // For Loop - int fooFor; //for loop structure => for(; ; ) - for (fooFor = 0; fooFor < 10; fooFor++) + for (int fooFor = 0; fooFor < 10; fooFor++) { - //Console.WriteLine(fooFor); //Iterated 10 times, fooFor 0->9 } - Console.WriteLine("fooFor Value: " + fooFor); - - // For Each Loop + + // For Each Loop // foreach loop structure => foreach( in ) - // The foreach loop loops over any object implementing IEnumerable or IEnumerable - // All the collection types (Array, List, Dictionary...) in the .Net framework - // implement one or both of these interfaces. - // (The ToCharArray() could be removed, because a string also implements IEnumerable) + // The foreach loop loops over any object implementing IEnumerable or IEnumerable + // All the collection types (Array, List, Dictionary...) in the .Net framework + // implement one or both of these interfaces. + // (The ToCharArray() could be removed, because a string also implements IEnumerable) foreach (char character in "Hello World".ToCharArray()) { - //Console.WriteLine(character); //Iterated over all the characters in the string } @@ -356,20 +279,18 @@ namespace Learning case 3: monthString = "March"; break; - // You can assign more than one case to an action - // But you can't add an action without a break before another case - // (if you want to do this, you would have to explicitly add a goto case x - case 6: - case 7: - case 8: - monthString = "Summer time!!"; - break; + // You can assign more than one case to an action + // But you can't add an action without a break before another case + // (if you want to do this, you would have to explicitly add a goto case x + case 6: + case 7: + case 8: + monthString = "Summer time!!"; + break; default: monthString = "Some other month"; break; } - Console.WriteLine("Switch Case Result: " + monthString); - /////////////////////////////////////// // Converting Data Types And Typecasting @@ -384,46 +305,227 @@ namespace Learning // try parse will default to type default on failure // in this case: 0 int tryInt; - int.TryParse("123", out tryInt); + if (int.TryParse("123", out tryInt)) // Funciton is boolean + Console.WriteLine(tryInt); // 123 // Convert Integer To String // Convert class has a number of methods to facilitate conversions Convert.ToString(123); + // or + tryInt.ToString(); + } - /////////////////////////////////////// - // Classes And Functions - /////////////////////////////////////// - - Console.WriteLine("\n->Classes & Functions"); - - // (definition of the Bicycle class follows) + /////////////////////////////////////// + // CLASSES - see definitions at end of file + /////////////////////////////////////// + public static void Classes() + { + // See Declaration of objects at end of file // Use new to instantiate a class Bicycle trek = new Bicycle(); // Call object methods - trek.speedUp(3); // You should always use setter and getter methods - trek.setCadence(100); + trek.SpeedUp(3); // You should always use setter and getter methods + trek.Cadence = 100; // ToString is a convention to display the value of this Object. - Console.WriteLine("trek info: " + trek.ToString()); - - // Instantiate another new Bicycle - Bicycle octo = new Bicycle(5, 10); - Console.WriteLine("octo info: " + octo.ToString()); + Console.WriteLine("trek info: " + trek.Info()); // Instantiate a new Penny Farthing PennyFarthing funbike = new PennyFarthing(1, 10); - Console.WriteLine("funbike info: " + funbike.ToString()); + Console.WriteLine("funbike info: " + funbike.Info()); Console.Read(); } // End main method + // CONSOLE ENTRY A console application must have a main method as an entry point + public static void Main(string[] args) + { + OtherInterestingFeatures(); + } + + // + // INTERESTING FEATURES + // + + // DEFAULT METHOD SIGNATURES + + public // Visibility + static // Allows for direct call on class without object + int // Return Type, + MethodSignatures( + int maxCount, // First variable, expects an int + int count = 0, // will default the value to 0 if not passed in + int another = 3, + params string[] otherParams // captures all other parameters passed to method + ) + { + return -1; + } + + // Methods can have the same name, as long as the signature is unique + public static void MethodSignature(string maxCount) + { + } + + // TEMPLATES + // The classes for TKey and TValue is specified by the user calling this function. + // This method emulates the SetDefault of Python + public static TValue SetDefault( + IDictionary dictionary, + TKey key, + TValue defaultItem) + { + TValue result; + if (!dictionary.TryGetValue(key, out result)) + return dictionary[key] = defaultItem; + return result; + } + + // You can narrow down the objects that are passed in + public static void IterateAndPrint(T toPrint) where T: IEnumerable + { + // We can iterate, since T is a IEnumerable + foreach (var item in toPrint) + // Item is an int + Console.WriteLine(item.ToString()); + } + + public static void OtherInterestingFeatures() + { + // OPTIONAL PARAMETERS + MethodSignatures(3, 1, 3, "Some", "Extra", "Strings"); + MethodSignatures(3, another: 3); // explicity set a parameter, skipping optional ones + + // EXTENSION METHODS + int i = 3; + i.Print(); // Defined below + + // NULLABLE TYPES - great for database interaction / return values + // any value type (i.e. not a class) can be made nullable by suffixing a ? + // ? = + int? nullable = null; // short hand for Nullable + Console.WriteLine("Nullable variable: " + nullable); + bool hasValue = nullable.HasValue; // true if not null + + // ?? is syntactic sugar for specifying default value (coalesce) + // in case variable is null + int notNullable = nullable ?? 0; // 0 + + // IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is: + var magic = "magic is a string, at compile time, so you still get type safety"; + // magic = 9; will not work as magic is a string, not an int + + // TEMPLATES + var phonebook = new Dictionary() { + {"Sarah", "212 555 5555"} // Add some entries to the phone book + }; + + // Calling SETDEFAULT defined as a template above + Console.WriteLine(SetDefault(phonebook, "Shaun", "No Phone")); // No Phone + // nb, you don't need to specify the TKey and TValue since they can be + // derived implicitly + Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555 + + // LAMBDA EXPRESSIONS - allow you to write code in line + Func square = (x) => x * x; // Last T item is the return value + Console.WriteLine(square(3)); // 9 + + // PARALLEL FRAMEWORK + // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx + var websites = new string[] { + "http://www.google.com", "http://www.reddit.com", + "http://www.shaunmccarthy.com" + }; + var responses = new Dictionary(); + + // Will spin up separate threads for each request, and join on them + // before going to the next step! + Parallel.ForEach(websites, + new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads + website => + { + // Do something that takes a long time on the file + using (var r = WebRequest.Create(new Uri(website)).GetResponse()) + { + responses[website] = r.ContentType; + } + }); + + // This won't happen till after all requests have been completed + foreach (var key in responses.Keys) + Console.WriteLine("{0}:{1}", key, responses[key]); + + // DYNAMIC OBJECTS (great for working with other languages) + dynamic student = new ExpandoObject(); + student.FirstName = "First Name"; // No need to define class first! + + // You can even add methods (returns a string, and takes in a string) + student.Introduce = new Func( + (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo)); + Console.WriteLine(student.Introduce("Beth")); + + // IQUERYABLE - almost all collections implement this, which gives you a lot of + // very useful Map / Filter / Reduce style methods + var bikes = new List(); + bikes.Sort(); // Sorts the array + bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sorts based on wheels + var result = bikes + .Where(b => b.Wheels > 3) // Filters - chainable (returns IQueryable of previous type) + .Where(b => b.IsBroken && b.HasTassles) + .Select(b => b.ToString()); // Map - we only this selects, so result is a IQueryable + + var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection + + // Create a list of IMPLICIT objects based on some parameters of the bike + var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles }); + // Hard to show here, but you get type ahead completion since the compiler can implicitly work + // out the types above! + foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome)) + Console.WriteLine(bikeSummary.Name); + + // ASPARALLEL + // And this is where things get wicked - combines 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 + // cores + + // LINQ - maps a store to IQueryable objects, with delayed execution + // e.g. LinqToSql - maps to a database, LinqToXml maps to an xml document + var db = new BikeRespository(); + + // execution is delayed, which is great when querying a database + var fitler = db.Bikes.Where(b => b.HasTassles); // no query run + if (42 > 6) // You can keep adding filters, even conditionally - great for "advanced search" functionality + fitler = fitler.Where(b => b.IsBroken); // no query run + + var query = fitler + .OrderBy(b => b.Wheels) + .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 + foreach (string bike in query) + Console.WriteLine(result); + + + + } } // End LearnCSharp class // You can include other classes in a .cs file + public static class Extensions + { + // EXTENSION FUNCTIONS + public static void Print(this object obj) + { + Console.WriteLine(obj.ToString()); + } + } // Class Declaration Syntax: // class { @@ -434,64 +536,88 @@ namespace Learning public class Bicycle { // Bicycle's Fields/Variables - public int cadence; // Public: Can be accessed from anywhere - private int _speed; // Private: Only accessible from within the class - protected int gear; // Protected: Accessible from the class and subclasses - internal int wheels; // Internal: Accessible from within the assembly - string name; // Everything is private by default: Only accessible from within this class + public int Cadence // Public: Can be accessed from anywhere + { + get // get - define a method to retrieve the property + { + return _cadence; + } + set // set - define a method to set a proprety + { + _cadence = value; // Value is the value passed in to to the setter + } + } + private int _cadence; + + protected virtual int Gear // Protected: Accessible from the class and subclasses + { + get; // creates an auto property so you don't need a member field + set; + } + + internal int Wheels // Internal: Accessible from within the assembly + { + get; + private set; // You can set modifiers on the get/set methods + } + + int _speed; // Everything is private by default: Only accessible from within this class. + // can also use keyword privatee + public string Name { get; set; } // 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). - // The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong. - // An enum can't contain the same value twice. - public enum Brand + // It is really just mapping a name to a value (an int, unless specified otherwise). + // The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong. + // An enum can't contain the same value twice. + public enum BikeBrand { AIST, BMC, - Electra=42, //you can explicitly set a value to a name + Electra = 42, //you can explicitly set a value to a name Gitane } // We defined this type inside a Bicycle class, so it is a nested type // Code outside of this class should reference this type as Bicycle.Brand - public Brand brand; // After declaring an enum type, we can declare the field of this type + public BikeBrand Brand; // After declaring an enum type, we can declare the field of this type // Static members belong to the type itself rather then specific object. - static public int bicyclesCreated = 0; // You can access them without a reference to any object: // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated); + static public int BicyclesCreated = 0; // readonly values are set at run time // they can only be assigned upon declaration or in a constructor - readonly bool hasCardsInSpokes = false; // read-only private + readonly bool _hasCardsInSpokes = false; // read-only private // Constructors are a way of creating classes // This is a default constructor - private Bicycle() + public Bicycle() { - gear = 1; - cadence = 50; + this.Gear = 1; // you can access mmebers of the object with the keyword this + Cadence = 50; // but you don't always need it _speed = 5; - name = "Bontrager"; - brand = Brand.AIST; - bicyclesCreated++; + Name = "Bontrager"; + Brand = BikeBrand.AIST; + BicyclesCreated++; } // This is a specified constructor (it contains arguments) public Bicycle(int startCadence, int startSpeed, int startGear, - string name, bool hasCardsInSpokes, Brand brand) + string name, bool hasCardsInSpokes, BikeBrand brand) + : base() // calls base first { - this.gear = startGear; // "this" keyword denotes the current object - this.cadence = startCadence; - this._speed = startSpeed; - this.name = name; // it can be useful when there's a name conflict - this.hasCardsInSpokes = hasCardsInSpokes; - this.brand = brand; + Gear = startGear; + Cadence = startCadence; + _speed = startSpeed; + Name = name; + _hasCardsInSpokes = hasCardsInSpokes; + Brand = brand; } // Constructors can be chained - public Bicycle(int startCadence, int startSpeed, Brand brand) : - this(startCadence, startSpeed, 0, "big wheels", true) + public Bicycle(int startCadence, int startSpeed, BikeBrand brand) : + this(startCadence, startSpeed, 0, "big wheels", true, brand) { } @@ -501,27 +627,8 @@ namespace Learning // classes can implement getters and setters for their fields // or they can implement properties (this is the preferred way in C#) - // Method declaration syntax: - // () - public int GetCadence() - { - return cadence; - } - - // void methods require no return statement - public void SetCadence(int newValue) - { - cadence = newValue; - } - - // virtual keyword indicates this method can be overridden in a derived class - public virtual void SetGear(int newValue) - { - gear = newValue; - } - // Method parameters can have default values. - // In this case, methods can be called with these parameters omitted + // In this case, methods can be called with these parameters omitted public void SpeedUp(int increment = 1) { _speed += increment; @@ -541,12 +648,12 @@ namespace Learning get { return _hasTassles; } set { _hasTassles = value; } } - - // You can also define an automatic property in one line - // this syntax will create a backing field automatically. - // You can set an access modifier on either the getter or the setter (or both) - // to restrict its access: - public bool IsBroken { get; private set; } + + // You can also define an automatic property in one line + // this syntax will create a backing field automatically. + // You can set an access modifier on either the getter or the setter (or both) + // to restrict its access: + public bool IsBroken { get; private set; } // Properties can be auto-implemented public int FrameSize @@ -558,13 +665,13 @@ namespace Learning } //Method to display the attribute values of this Object. - public override string ToString() + public virtual string Info() { - return "gear: " + gear + - " cadence: " + cadence + - " speed: " + _speed + - " name: " + name + - " cards in spokes: " + (hasCardsInSpokes ? "yes" : "no") + + return "Gear: " + Gear + + " Cadence: " + Cadence + + " Speed: " + _speed + + " Name: " + Name + + " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") + "\n------------------------------\n" ; } @@ -573,9 +680,10 @@ namespace Learning public static bool DidWeCreateEnoughBycles() { // Within a static method, we only can reference static class members - return bicyclesCreated > 9000; + return BicyclesCreated > 9000; } // If your class only needs static members, consider marking the class itself as static. + } // end class Bicycle // PennyFarthing is a subclass of Bicycle @@ -586,20 +694,27 @@ namespace Learning // calling parent constructor public PennyFarthing(int startCadence, int startSpeed) : - base(startCadence, startSpeed, 0, "PennyFarthing", true) + base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra) { } - public override void SetGear(int gear) + protected override int Gear { - gear = 0; + get + { + return 0; + } + set + { + throw new ArgumentException("You can't change gears on a PennyFarthing"); + } } - public override string ToString() + public override string Info() { string result = "PennyFarthing bicycle "; result += base.ToString(); // Calling the base version of the method - return reuslt; + return result; } } @@ -624,7 +739,7 @@ namespace Learning damage += meters; } - public void Broken + public bool Broken { get { @@ -632,24 +747,34 @@ namespace Learning } } } -} // End Namespace + /// + /// 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 + /// + public class BikeRespository : DbSet + { + public BikeRespository() + : base() + { + } + + public DbSet Bikes { get; set; } + } +} // End Namespace ``` ## Topics Not Covered * Flags * Attributes - * Generics (T), Delegates, Func, Actions, lambda expressions * Static properties * Exceptions, Abstraction - * LINQ * ASP.NET (Web Forms/MVC/WebMatrix) * Winforms * Windows Presentation Foundation (WPF) - - ## Further Reading * [DotNetPerls](http://www.dotnetperls.com) -- cgit v1.2.3 From eccc9e094832350842f16f3a7666aa633748098b Mon Sep 17 00:00:00 2001 From: Shaun McCarthy Date: Sat, 26 Oct 2013 15:27:53 -0400 Subject: Reanmed to Generics instead of templates --- csharp.html.markdown | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/csharp.html.markdown b/csharp.html.markdown index f4c30b03..8c15b86f 100644 --- a/csharp.html.markdown +++ b/csharp.html.markdown @@ -150,7 +150,7 @@ on a new line! ""Wow!"", the masses cried"; List intList = new List(); List stringList = new List(); List z = new List { 9000, 1000, 1337 }; // intialize - // The <> are for templates - Check out the cool stuff section + // The <> are for generics - Check out the cool stuff section // Lists don't default to a value; // A value must be added before accessing the index @@ -369,7 +369,7 @@ on a new line! ""Wow!"", the masses cried"; { } - // TEMPLATES + // GENERICS // The classes for TKey and TValue is specified by the user calling this function. // This method emulates the SetDefault of Python public static TValue SetDefault( @@ -417,12 +417,13 @@ on a new line! ""Wow!"", the masses cried"; var magic = "magic is a string, at compile time, so you still get type safety"; // magic = 9; will not work as magic is a string, not an int - // TEMPLATES + // GENERICS + // var phonebook = new Dictionary() { {"Sarah", "212 555 5555"} // Add some entries to the phone book }; - // Calling SETDEFAULT defined as a template above + // Calling SETDEFAULT defined as a generic above Console.WriteLine(SetDefault(phonebook, "Shaun", "No Phone")); // No Phone // nb, you don't need to specify the TKey and TValue since they can be // derived implicitly -- cgit v1.2.3