The code copy is as follows:
// Single line comment starts with //
/*
This is how multi-line comments are
*/
/// <summary>
/// XML document comments
/// </summary>
// Declare the namespace used by the application
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;
using System.IO;
// Define the scope and organize the code into packages
namespace Learning
{
// Each .cs file needs to contain at least one class with the same file name as
// You may not do this, but this is not good.
public class LearnCSharp
{
// If you have used Java or C++ before, you can jump directly to the following text "Interesting Features"
public static void Syntax()
{
// Use Console.WriteLine to print information
Console.WriteLine("Hello World");
Console.WriteLine(
"Integer: " + 10 +
" Double: " + 3.14 +
" Boolean: " + true);
// Print with Console.Write without line break symbol
Console.Write("Hello");
Console.Write("World");
////////////////////////////////////////////////// /
// Types and variables
//
// Use <type> <name> to define variables
////////////////////////////////////////////////// /
// Sbyte - signed 8-bit integer
// (-128 <= sbyte <= 127)
sbyte fooSbyte = 100;
// Byte - Unsigned 8-bit integer
// (0 <= byte <= 255)
byte fooByte = 100;
// Short - 16-bit integer
// Signed - (-32,768 <= short <= 32,767)
// Unsigned - (0 <= ushort <= 65,535)
short fooShort = 10000;
ushort fooUshort = 10000;
// 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)
// Long - 64-bit integer
long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
ulong fooUlong = 10000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
// The number defaults to int or uint (depending on the size)
// Use L to indicate the variable value type as long or ulong
// Double - Double 64-bit IEEE 754 floating point number
double fooDouble = 123.4; // Accuracy: 15-16 bits
// Float - Single precision 32-bit IEEE 754 floating point number
float fooFloat = 234.5f; // Accuracy: 7 bits
// Use f to indicate the variable value type is float
// Decimal - 128-bits data type, with higher accuracy than other floating point types, suitable for finance and finance
decimal fooDecimal = 150.3m;
// Boolean value - true & false
bool fooBoolean = true; // or false
// Char - Single 16-bit Unicode character
char fooChar = 'A';
// Strings -- Unlike the previous basic type, a string is not a value, but a reference. This means you can set the string to null.
string fooString = "/"escape/" quotes and add /n (new lines) and /t (tabs)";
Console.WriteLine(fooString);
// You can access each character of a string through the index:
char charFromString = fooString[1]; // => 'e'
// String cannot be modified: fooString[1] = 'X' does not work.
// Compare strings according to the current locale settings, case insensitive
string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
// String formatting based on sprintf
string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
// Date and format
DateTime fooDate = DateTime.Now;
Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
// Use the @ symbol to create strings across lines. Use "" to represent"
string bazString = @"Here's some stuff
on a new line! ""Wow!"", the masses cried";
// Use const or read-only to define constants, and constants are computed during compilation
const int HOURS_I_WORK_PER_WEEK = 9001;
////////////////////////////////////////////////// /
// Data structure
////////////////////////////////////////////////// /
// Array - Counting starts from 0. When declaring an array, you need to determine the array length.
// The format of declaring an array is as follows:
// <datatype>[] <var name> = new <datatype>[<array size>];
int[] intArray = new int[10];
// Other ways to declare and initialize arrays:
int[] y = { 9000, 1000, 1337 };
// Access the elements of the array
Console.WriteLine("intArray @ 0: " + intArray[0]);
// Array can be modified
intArray[1] = 1;
// List
// Lists are more commonly used than arrays because lists are more flexible.
// The format of the declaration list is as follows:
// List<datatype> <var name> = new List<datatype>();
List<int> intList = new List<int>();
List<string> stringList = new List<string>();
List<int> z = new List<int> { 9000, 1000, 1337 }; // Intialize
// <> For generics - refer to the following
// There is no default value for the list. When accessing the list element, you must first add the element.
intList.Add(1);
Console.WriteLine("intList @ 0: " + intList[0]);
// Other data structures:
// Stack/queue
// Dictionary (Implementation of hash table)
// Hash collection
// Read-only collection
// Tuple (.Net 4+)
///////////////////////////////////////
// Operator
///////////////////////////////////////
Console.WriteLine("/n->Operators");
int i1 = 1, i2 = 2; // Abbreviation of multiple declarations
// Direct arithmetic
Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
// Take the rest
Console.WriteLine("11%3 = " + (11%3)); // => 2
// Compare operators
Console.WriteLine("3 == 2? " + (3 == 2)); // => false
Console.WriteLine("3 != 2? " + (3 != 2)); // => true
Console.WriteLine("3 > 2? " + (3 > 2)); // => true
Console.WriteLine("3 < 2? " + (3 < 2)); // => false
Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
// bit operator
/*
~ Reverse
<< Move left (signed)
>> Move right (signed)
& and
^ bitwise xor
| or
*/
// Self-increase, self-decrease
int i = 0;
Console.WriteLine("/n->Inc/Dec-rementation");
Console.WriteLine(i++); //i = 1. Increase afterwards
Console.WriteLine(++i); //i = 2. Initial increase
Console.WriteLine(i--); //i = 1. Self-decreasing afterwards
Console.WriteLine(--i); //i = 0. Self-decreasing in advance
///////////////////////////////////////
// Control structure
///////////////////////////////////////
Console.WriteLine("/n->Control Structures");
// If statement similar to C
int j = 10;
if (j == 10)
{
Console.WriteLine("I get printed");
}
else if (j > 10)
{
Console.WriteLine("I don't");
}
else
{
Console.WriteLine("I also don't");
}
// Tripartite expression
// A simple if/else statement can be written as:
// <condition> ? <true> : <false>
string isTrue = (true) ? "True" : "False";
// While loop
int fooWhile = 0;
While (fooWhile < 100)
{
//Iterations 100 times, fooWhile 0->99
fooWhile++;
}
// Do While Loop
int fooDoWhile = 0;
do
{
//Iterations 100 times, fooDoWhile 0->99
fooDoWhile++;
} while (fooDoWhile < 100);
//for loop
//for loop structure => for(<initial condition>; <condition>; <step>)
for (int fooFor = 0; fooFor < 10; fooFor++)
{
//Iterations 10 times, fooFor 0->9
}
// foreach loop
// foreach loop structure => foreach(<iter type> <iter> in <enumerable structure>)
// The foreach loop is suitable for any object that implements IEnumerable or IEnumerable.
// Collection types (arrays, lists, dictionaries...) under the .Net framework all implement these interfaces.
// In the following code, ToCharArray() can be deleted because the string also implements IEnumerable.
foreach (char character in "Hello World".ToCharArray())
{
//Iterate through all characters in the string
}
// Switch statement
// switch is suitable for byte, short, char and int data types.
// Also applicable to enumerable types, including string classes,
// and some classes that encapsulate original values: Character, Byte, Short, and Integer.
int month = 3;
string monthString;
switch (month)
{
case 1:
monthString = "January";
break;
case 2:
monthString = "February";
break;
case 3:
monthString = "March";
break;
// You can match multiple case statements at once
// But you need to use break after adding the case statement
// (Otherwise you need to explicitly use the goto case x statement)
case 6:
case 7:
case 8:
monthString = "Summer time!!";
break;
default:
monthString = "Some other month";
break;
}
///////////////////////////////////////
// Convert the string to an integer, and an exception will be thrown if the conversion fails:
///////////////////////////////////////
// Converting data
// Convert the string to an integer, and an exception will be thrown if the conversion fails:
int.Parse("123");//Return "123" of integer type
// TryParse will try to convert the type, and if it fails, it will return the default type, such as 0
int tryInt;
if (int.TryParse("123", out tryInt)) // Funciton is boolean
Console.WriteLine(tryInt); // 123
// Convert integers to strings
// Convert class provides a series of convenient conversion methods
Convert.ToString(123);
// or
tryInt.ToString();
}
///////////////////////////////////////
// kind
///////////////////////////////////////
public static void Classes()
{
// See the object declaration at the end of the file
// Initialize the object with new
Bicycle trek = new Bicycle();
// Call the object method
trek.SpeedUp(3); // You should always use setter and getter methods
trek.Cadence = 100;
// View the object's information.
Console.WriteLine("trek info: " + trek.Info());
// Instantiate a new Penny Farthing
PennyFarthing funbike = new PennyFarthing(1, 10);
Console.WriteLine("funbike info: " + funbike.Info());
Console.Read();
} // End main method
// Terminal program Terminal program must have a main method as the entry
public static void Main(string[] args)
{
OtherInterestingFeatures();
}
//
// Interesting features
//
// Default method signature
public // Visibility
static // allows direct calls to classes without creating instances first
int // Return value
MethodSignatures(
int maxCount, // The first variable, type is an integer
int count = 0, // If no incoming value is passed, the default value is 0
int another = 3,
params string[] otherParams // Capture other parameters
)
{
return -1;
}
// The method can be renamed as long as the signature is different
public static void MethodSignature(string maxCount)
{
}
// Generics
// The TKey and TValue classes are specified when calling the function with the user.
// The following function simulates Python's SetDefault
public static TValue SetDefault<TKey, TValue>(
IDictionary<TKey, TValue> dictionary,
TKey key,
TValue defaultItem)
{
TValue result;
if (!dictionary.TryGetValue(key, out result))
return dictionary[key] = defaultItem;
return result;
}
// You can limit the range of incoming values
public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
{
// We can iterate because T is enumerable
foreach (var item in toPrint)
// ittm is an integer
Console.WriteLine(item.ToString());
}
public static void OtherInterestingFeatures()
{
// Optional parameters
MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
MethodSignatures(3, another: 3); // Specify parameters explicitly, ignore optional parameters
// Extend method
int i = 3;
i.Print(); // See the definition below
// Can be null type is very useful for database interaction and return values.
// Any value type (ie is not a class) will be added to a nullable type after adding a suffix?
// <type>? <variable name> = <value>
int? nullable = null; // Abbreviation of Nullable<int>
Console.WriteLine("Nullable variable: " + nullable);
bool hasValue = nullable.HasValue; // Return true if not null
// ?? is syntactic sugar used to specify default values
// In case the variable is null
int notNullable = nullable ?? 0; // 0
//Variable type inference
// You can let the compiler infer variable types:
var magic = "magic is a string, at compile time, so you still get type safety";
// magic = 9; // does not work because magic is a string, not an integer.
// Generics
//
var phonebook = new Dictionary<string, string>() {
{"Sarah", "212 555 5555"} // Add new entry to the phone book
};
// Call SETDEFAULT defined above as generic
Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // No phone
// You don't need to specify TKey or TValue, because they will be implicitly derived
Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555
// lambda expression - allows you to solve functions with one line of code
Func<int, int> square = (x) => x * x; // The last item is the return value
Console.WriteLine(square(3)); // 9
// Abandonable resource management - allows you to easily deal with unmanaged resources. Most objects that access unmanaged resources (file operators, device context, etc.) implement the IDisposable interface.
// The using statement will clean up the IDisposable object for you.
using (StreamWriter writer = new StreamWriter("log.txt"))
{
writer.WriteLine("Nothing suspicious here");
// At the end of the scope, the resource will be recycled
// (Even if an exception is thrown, it will still be recycled)
}
// 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<string, string>();
// Open a new thread for each request and merge the results before running 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;
}
});
// The following code will not be run until all requests are completed
foreach (var key in responses.Keys)
Console.WriteLine("{0}:{1}", key, responses[key]);
// Dynamic objects (it is very convenient to use with other languages)
dynamic student = new ExpandoObject();
student.FirstName = "First Name"; // There is no need to define the class first!
// You can even add methods (accept a string, output a string)
student.Introduce = new Func<string, string>(
(introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
Console.WriteLine(student.Introduce("Beth"));
// IQUERYABLE<T> - Almost all collections implement it, bringing you a Map/Filter/Reduce style approach
var bikes = new List<Bicycle>();
bikes.Sort(); // Sorts the array
bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sort by number of wheels
var result = bikes
.Where(b => b.Wheels > 3) // Filter - Can be used in chains (return to IQueryable)
.Where(b => b.IsBroken && b.HasTassles)
.Select(b => b.ToString()); // Map - Here we use select, so the result is IQueryable<string
var sum = bikes.Sum(b => b.Wheels); // Reduce - Calculate the total number of wheels in the set
// Create a list of implicit objects generated based on some parameters of the bicycle
var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
// It is difficult to demonstrate, but the compiler can deduce the above object types before the code is compiled.
foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
Console.WriteLine(bikeSummary.Name);
// ASPARALLEL
// Evil characteristics - combining linq and parallel operations
var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
// The above code will run concurrently. The thread will be automatically opened and the results will be calculated separately. Suitable for multi-core and large-data scenarios.
// LINQ - Map IQueryable<T> to storage, delay execution, such as LinqToSql mapping database, LinqToXml mapping XML documents.
var db = new BikeRespository();
// Execution is delayed, which is good for querying the database
var filter = db.Bikes.Where(b => b.HasTassles); // Don't run the query
if (42 > 6) // You can continuously increase filtering, including conditional filtering, for example for the Advanced Search feature
filter = filter.Where(b => b.IsBroken); // Don't run the query
var query = filter
.OrderBy(b => b.Wheels)
.ThenBy(b => b.Name)
.Select(b => b.Name); // The query is still not running
// Now run the query, and a reader will be opened when running the query, so you iterate over a copy
foreach (string bike in query)
Console.WriteLine(result);
}
} // End LearnCSharp class
// You can include other classes in the same .cs file
public static class Extensions
{
// Extended function
public static void Print(this object obj)
{
Console.WriteLine(obj.ToString());
}
}
// Declare the syntax of the class:
// <public/private/protected/internal> class <class name>{
// //Data fields, constructors, internal functions.
/// In Java, functions are called methods.
// }
public class Bicycle
{
// Bicycle fields and variables
public int Cadence // Public: accessible anywhere
{
get // get - define a method to get attributes
{
return _cadence;
}
set // set - define a method to set properties
{
_cadence = value; // value is the value passed to the setter
}
}
private int _cadence;
protected virtual int Gear // Classes and subclasses can be accessed
{
get; // Create an automatic property without member fields
set;
}
internal int Wheels // Internal: Can be accessed within the same assembly
{
get;
Private set; // You can add modifiers to the get/set method
}
int _speed; // Default is private: It can only be accessed within this class, you can also use the `private` keyword
public string Name { get; set; }
//The enum type contains a set of constants that map the name to the value (unless otherwise specified, an integer).
//The types of the enmu element can be byte, sbyte, short, ushort, int, uint, long, ulong. Enum cannot contain the same value.
public enum BikeBrand
{
AIST,
BMC,
Electra = 42, //You can explicitly assign values
Gitane // 43
}
// This type we define in the Bicycle class, so it is an inline type. Code outside of this class should be referenced using Bicycle.Brand.
public BikeBrand Brand; // After declaring an enum type, we can declare fields of this type
// Static method
// The type of the static method is itself and does not belong to a specific object. You can access them without referencing objects.
static public int BicyclesCreated = 0;
// Read-only value
// Read-only values are determined at runtime and they can only be assigned values within the declaration or constructor.
readonly bool _hasCardsInSpokes = false; // read-only private
// Constructors are a way to create classes.
// Below is a default constructor.
public Bicycle()
{
this.Gear = 1; // You can use the keyword this to access the object's members
Cadence = 50; // But you don't always need it
_speed = 5;
Name = "Bontrager";
Brand = BikeBrand.AIST;
BicyclesCreated++;
}
// Another example of constructor (including parameters)
public Bicycle(int startCadence, int startSpeed, int startGear,
string name, bool hasCardsInSpokes, BikeBrand brand)
: base() // First call base
{
Gear = startGear;
Cadence = startCadence;
_speed = startSpeed;
Name = name;
_hasCardsInSpokes = hasCardsInSpokes;
Brand = brand;
}
// The constructor can be used in chains
public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
this(startCadence, startSpeed, 0, "big wheels", true, brand)
{
}
// Function syntax:
// <public/private/protected> <return value> <function name>(<parameter>)
// Classes can implement getters and setters methods for their fields for fields, or they can implement properties (C# recommended to use this).
// The parameters of the method can have default values. In the case of default values, the corresponding parameters can be omitted when calling the method.
public void SpeedUp(int increment = 1)
{
_speed += increment;
}
public void SlowDown(int decrement = 1)
{
_speed -= decline;
}
// Properties can access and set values. When only data needs to be accessed, consider using properties. Attributes can define get and set, or both.
private bool _hasTassles; // private variable
public bool HasTassles // public accessor
{
get { return _hasTassles; }
set { _hasTassles = value; }
}
// You can define automatic properties within one line, and this syntax will automatically create fallback fields. You can set access modifiers for getters or setters to limit their access.
public bool IsBroken { get; private set; }
// The implementation of attributes can be automatic
public int FrameSize
{
get;
// You can specify access modifiers for get or set
// The following code means that only the Bicycle class can call the Framesize set
private set;
}
// Method to display object properties
public virtual string Info()
{
return "Gear: " + Gear +
" Cadence: " + Cadence +
" Speed: " + _speed +
" Name: " + Name +
" Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") +
"/n-----------------------------/n"
}
// The method can be static. Usually used in auxiliary methods.
public static bool DidWeCreateEnoughBycles()
{
// In static methods, you can only refer to static members of the class
return BicyclesCreated > 9000;
} // If your class only needs static members, consider taking the entire class as a static class.
} // Bicycle class ends
// PennyFarthing is a subclass of Bicycle
class PennyFarthing : Bicycle
{
// (Penny Farthings is a bike with a big front wheel. No gears.)
// Call the parent constructor
public PennyFarthing(int startCadence, int startSpeed) :
base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra)
{
}
protected override int Gear
{
get
{
return 0;
}
set
{
throw new ArgumentException("You can't switch gears on PennyFarthing");
}
}
public override string Info()
{
string result = "PennyFarthing bicycle ";
result += base.ToString(); // Call parent method
return result;
}
}
// The interface only contains the signature of the member, and is not implemented.
interface IJumpable
{
void Jump(int meters); // All interface members are implicitly exposed
}
interface IBreakable
{
bool Broken { get; } // The interface can contain properties, methods and events
}
// Classes can only inherit one class, but they can implement any number of interfaces
class MountainBike : Bicycle, IJumpable, IBreakable
{
int damage = 0;
public void Jump(int meters)
{
damage += meters;
}
public bool Broken
{
get
{
return damage > 100;
}
}
}
/// <summary>
/// Connect to the database, an example of LinqToSql. EntityFramework Code First is great (similar to Ruby's ActiveRecord, but it's two-way)
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
/// </summary>
public class BikeRespository : DbSet
{
public BikeRespository()
: base()
{
}
public DbSet<Bicycle> Bikes { get; set; }
}
} // End Namespace
Note that the topics not covered are:
1.Flags
2.Attributes
3. Static properties
4.Exceptions, Abstract
6.ASP.NET (Web Forms/MVC/WebMatrix)
6. Winforms
7. Windows Presentation Foundation (WPF)