Skip to content

Latest commit

 

History

History
451 lines (333 loc) · 12.9 KB

csharp_quick_tutorial.md

File metadata and controls

451 lines (333 loc) · 12.9 KB

...menustart

...menuend

C# vs .NET

  • C# is a programming language
  • .NET is a framework for building applications on Windows
    • .NET framework is not limited to c#. There are different languages that can target that framework and build applications using that framwork, e.g. F#, vb.net.
    • .NET framework contains 2 components
      1. CLR(Common Language Runtime)
      2. Class Library

CLR (Common Language Runtime)

  • When you compile your C# code, the result is what we called IL(intermediate language) code. It is independent of the computer on which it's running.
    • Now we need something that would translate the IL code into the native code on the machine that running the application. And that is the job of CLR.
  • So CLR is essentially an application that is sitting in the memory whose job is to translate the IL code into the machine code,
    • and this process is called just-in-time compilation or JIT.

Architecture of .NET Applications

  • Class
    • building blocks
  • Namespace
    • a way to organize these classes
    • a container of related classes
  • Assembly (DLL or EXE)
    • as the namespaces grow we need a different way of partitioning an application.
    • an assembly is a container for related namespaces
    • physically it's a file on the disk. It can either be an executable or a DLL.

Fundamental

ref vs out

Both ref and out parameter treated same at compile-time but different at run-time.

scenario ref out
before entering method must initialize
before returning must initialize inside the mothod
when to use when the callee also want to change the value of passed parameter when a method return multiple values

yield

  • Usage of the "yield" keyword indicates that the method it appears in is an Iterator
    • this means you can use it in a foreach loop
      public static IEnumerable<int> YieldCounter(int limit = 10)
      {
          for (var i = 0; i < limit; i++)
              yield return i;
      }
    • which you would call like this :
      public static void PrintYieldCounterToConsole()
      {
          foreach (var counter in YieldCounter())
              Console.WriteLine(counter);
      }

extension method

  • allows you to add new methods in the existing class or in the structure without modifying the source code of the original type
    // static class
    public static class Extensions
    {
        // EXTENSION METHODS
        public static void Print(this object obj)
        {
            Console.WriteLine(obj.ToString());
        }
    }
    • this method extend to all object type
    • the first paramter this object obj is called Binding parameter
  • how 2 use
    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 ?
    • <type>? <var name> = <value>
    int? nullable = null; // short hand for Nullable<int>
    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
  • ?. is an operator for null-propagation - a shorthand way of checking for null
    // Use the Print() extension method if nullable isn't null
    nullable?.Print();

LAMBDA EXPRESSIONS

  • allow you to write code in line
    Func<int, int> square = (x) => x * x; // Last T item is the return 

disposable resources management

  • Let you handle unmanaged resources easily.
  • Most of objects that access unmanaged resources (file handle, device contexts, etc.)
  • implement the IDisposable interface. The using statement takes cleaning those IDisposable objects for you.
    using (StreamWriter writer = new StreamWriter("log.txt"))
    {
        writer.WriteLine("Nothing suspicious here");
        // At the end of scope, resources will be released.
        // Even if an exception is thrown.
    }

PARALLEL FRAMEWORK

https://devblogs.microsoft.com/csharpfaq/parallel-programming-in-net-framework-4-getting-started/

var words = new List<string> {"dog", "cat", "horse", "pony"};

Parallel.ForEach(words,
    new ParallelOptions() { MaxDegreeOfParallelism = 4 },
    word =>
    {
        Console.WriteLine(word);
    }
);

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<string, string>(
    (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));

IQUERYABLE < T >

  • almost all collections implement this, which gives you a lot of very useful Map / Filter / Reduce style methods
    var bikes = new List<Bicycle>();
    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<string>
    
    var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection

DELEGATES AND EVENTS

delegate

  • A delegate is a reference to a method.
    • data & method
      public static int count = 0;
      public static int Increment() {
          return ++count;
      }
    • To reference the Increment method, first declare a delegate with the same signature
      • i.e. takes no arguments and returns an int
      // first declare a delegate with same signature 
      public delegate int IncrementDelegate();
  • How to use
    • instantiating the delegate, and passing the method in as an argument
      IncrementDelegate inc = new IncrementDelegate(Increment);
    • works like a function pointer
      inc(); // => 1
    • Delegates can be composed with the + operator
      IncrementDelegate composedInc = inc;
      composedInc += inc;
      composedInc += inc;
      // composedInc will run Increment 3 times
      composedInc(); // => 4
    • word as a function parameter
      void someMethod( Mydelegate mydelegate ) {
          mydelegate( arg1, arg2 );
      }
      ...
      someMethond( new Mydelegate( somefunc ) );

event

  • event allows only +=, -= operators
  • An event can also be used to trigger delegates
    // Create an event with the delegate type
    public static event IncrementDelegate MyEvent;
  • How to use
    • 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
      MyEvent(); 

Why do we need events when we have delegates?

  1. To provide encapsulation and not exposing business logic.
    • delegate need instantiate, it maybe null. but delegate can be invoked directly without checking.
      • solve the problem by adding the event keyword.
    • event can not be invoked directly, it will raise an error.
  2. To prevent Team Client from clearing all assign methods to delegates
    • (You cannot do that for events):
      MyEvent = null;

OOP

  • constructor
    // This is a specified constructor (it contains arguments)
    public Bicycle(int startCadence, int startSpeed, int startGear,
                   string name, bool hasCardsInSpokes, BikeBrand brand)
        : base(startCadence, startSpeed) // calls base first
    {
        Gear = startGear;
        Cadence = startCadence;
        _speed = startSpeed;
        Name = name;
        _hasCardsInSpokes = hasCardsInSpokes;
        Brand = brand;
    }
    
    // Constructors can be chained
    public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
        this(startCadence, startSpeed, 0, "big wheels", true, brand)
    {
    }
  • override
    public override string Info()
    {
        string result = "PennyFarthing bicycle ";
        result += base.ToString(); // Calling the base version of the method
        return result;
    }

struct

  struct class
type value type reference type
alloc in stack, or inline in containing types, auto-deallocated in heap, GC
assignment copy value copy reference
  • when to use structure ?
    • CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.
    • ❌ AVOID defining a struct unless the type has all of the following characteristics:
      • It logically represents a single value, similar to primitive types (int, double, etc.).
      • It has an instance size under 16 bytes.
      • It is immutable.
      • It will not have to be boxed frequently.

boxing

{
    ...
    int someNumber = 420;
    object someNumberObject = someNumber;  // boxing , 20x slower
    int unboxed = (int)someNumberObject ; // unboxing , 4x slower
    ...
}
  • why is it called boxing ?

    • since object is a reference type allocated on the heap, you have to put that someNumber variable in a box and allocate on the heap.
  • another example

    var arrayOfInts = Enumerable.Range(69,420).ToArray();
    
    var arrayList = new ArrayList(arrayOfInts) ; // boxing, since underlying data structure is object[]
    var list = new List<int>(arrayOfInts); // will not boxing, generic solve that problem

compile & run C# code

# example cs

using System;

class cMain {
    static void Main(String[] args) {
        if ( args.Length < 1 ) {
            Console.WriteLine( "usage: resp_verify  <server response string>" );
            return ;
        }
        string data = args[0];
        Console.WriteLine( DOT_RESP_verify.resp_verify( data  ) ) ;
    }
}
#!/bin/sh
set -e

# compile
#  -r:xxx.dll   to reference an external dll
csc  /out:resp_verify.exe  *.cs

# run
mono resp_verify.exe '{"data":{"time":1626939359},"errcode":-1,"sig":"97f5e396ea0cadd9"}'