C# Basics and Events Technion - Israel Institute of Technology - Last Update : Natan Bagrov & Oren Afek, June 2017 - Webcourse

Page created by Pamela Padilla
 
CONTINUE READING
C# Basics and Events Technion - Israel Institute of Technology - Last Update : Natan Bagrov & Oren Afek, June 2017 - Webcourse
C# Basics and Events
   Technion - Israel Institute of Technology

Last Update : Natan Bagrov & Oren Afek, June 2017

                                                    1
C# Basics and Events Technion - Israel Institute of Technology - Last Update : Natan Bagrov & Oren Afek, June 2017 - Webcourse
C#
• If programming languages were weapons ….

 C# is a powerful laser rifle strapped to a donkey, when
 taken off the donkey the laser doesn’t seem to work as
                            well.
      https://9gag.com/gag/anXEbe0/if-programming-languages-were-weapons   2
C# Basics and Events Technion - Israel Institute of Technology - Last Update : Natan Bagrov & Oren Afek, June 2017 - Webcourse
Basic Program
                       hello.cs
using System;

public class MyClass
{
       public static void Main(string[] args)
       {
          Console.WriteLine("Hello, World!");
       }
}

   C:\> csc hello.cs
   … …
   C:\> hello.exe
                                                         3
                  236703 - Object-oriented Programming
C# Basics and Events Technion - Israel Institute of Technology - Last Update : Natan Bagrov & Oren Afek, June 2017 - Webcourse
Genealogy
• Designer: Anders Hejlsberg (Microsoft)
   – Designer of Turbo Pascal, Visual J++, Delphi (Borland)
• C Dynasty: Play on Words
   – C++ - increment C by one, C# - the musical note half tone above C
• Yet another curly bracket programming language
   – Grouping: {}
   – Terminstic camp: statements terminated by ";"
   – C operators: ++ % != += && & ^, >>, ?: …
   – C like control:
       • if () … else …
       • for (…; …; …) … break …, while (…) … continue …, do … while (…)
       • switch (…) … case … default (no fall through, works on strings)
                                                                           4
                       236703 - Object-oriented Programming
Design Principals
All the Good Things: Simplicity, General Purpose, Portability, Object Oriented
•   Programmer Protection:
     – Strong Nominative Typing
     – Array Bounds Checking – Throws exception when out of bounds
     – Garbage Collection – Unless using unmanaged resources (same as Java)
     – Check against using uninitialized variables
•   Evolutionary: dramatic changes in each language version
     – Learned from Java mistakes (no checked exceptions, since Anders Hejlsberg
       doesn't know yet how to do these right)
•   Differences From Java?
     – Developed by Microsoft
     – Runs on CLR "Common Language Runtime“ (JVM @ Java)
     – Compiles to the CIL "Common Intermediate Language“ (Bytecode @ Java)
     – Support for "unsafe" features, including pointers. (N/A in Java)            5

     – Anonymous types. (N/A in Java)
Object Oriented Purity
• Global Variables? No
   – All variables are defined in functions/classes
• Global Routines? No
   – All routines (functions) are defined in classes
• Non OO Types? No
   – Even primitive types belong in the OO hierarchy           1.Equals(2) is legal

• OO Control Flow? No
   – If, while, for, … are imperative statements
• Pre-processor? Yes
   – Only conditional compilation and compiler directives

                                                                                 6
                        236703 - Object-oriented Programming
Value/Reference Semantics
• Value Types
   – Simple types: char, int, float, …
   – Enum types
                     public enum Color {Red, Blue, Green}
   – Struct types

                      public struct Point { public int x, y; }
   – Nullable Value Types (next slide)
   – Wrapper Types: Int32 (int), Double (double), String (string), etc…
• Reference Types
   – Classes, Interfaces, Delegates

                                                                          7
                       236703 - Object-oriented Programming
Nullable Value Types
• Nullable types are built-in value types wrapped with an ability
  to contain null.
    Back in the early, cold and unpleasant times of MATAM:

 int getNumberOfOrdersOnlyFirstCustomer(Customer* customers){
     if(customers == NULL){
         // throw? Maybe return -1?
     }
     if(customers[0] == NULL){
         // throw? Maybe return -1?
     }
     if(customers[0]->orders == NULL){
         // throw? Maybe return -1?
     }
     return customers[0]->orders->getSize());
 }
                                                                8
                     236703 - Object-oriented Programming
Nullable Value Types
• Nullable types are built-in value types wrapped with an ability
  to contain null.
• C#’s way of defining the Optional Monad (of Java 8).
  int? GetNumberOfOrdersOnlyFirstCustomer(
                              ICollection customers){
      return customers?[0]?.Orders?.Count();
  }
  ?. Is syntactic suger: if the receiver is null then return null. Else, make the operation on it.

• Variable of T? can hold either a T value or null.
   •   T must be value-type. No point using reference types, since they can be
       assigned with null anyway.
   •   Use t.HasValue property to indicate if there is a value
   •   Use t.Value property to get the unwrap and get the value
                                                                                                     9
                                   236703 - Object-oriented Programming
Inheritance Hierarchy
• Classes:
     – Single Inheritance with common root: System.Object
     – Unified type system: includes all built-in types
           • System.ValueType: base class of all value types
                • Including void which is an alias for Object
Inheritance and Binding
• Method Binding: static, unless method is declared virtual
   – virtual modifier cannot go with any of static, abstract,
     private or override modifiers.
   – Properties can be virtual
• Overriding: inheritance is strict by default.
   – Overriding methods must be declared as such with override
     keyword
   – Cannot override non-virtual functions – will not compile
   – Use new modifier to indicate hiding – compiler will warn
• Sealing: use sealed keyword to indicate that an overriding
  function cannot be overridden further
   – No point in sealing a "plain" virtual function.
                                                                      11
                                                                 11
Naming Conventions
• Local variables & Fields : camelCase
   – string personName;

• Classes, Enums, Structs, Methods and Properties :
  each word starts with a capital Letter (PascalCase)
   – class Person { ... }
   – void PrintPersonName(Person p)

• Interfaces : starts with an I prefix
   – interface IEnumerable { ... }
                                                        12
Properties
• Property: a field implemented with methods
• Varieties: read only, write only, read-write
• Contextual keywords: get, set, value (also add and del for events)
   – Provide specific meaning in the code (not otherwise reserved)

 public class Person
 {
    private string name;
    public string Name
    {
      get { return this.name; }
      set                              Person p = new Person();
      {                                p.Name = “Eran Gilad”; //set
          if (value != “”)             Console.WriteLine(p.Name); //get
         {
             this.name = value;
         }
      }
    }
 }
                                                                      16
                                                                       16
Auto Properties

• Starting from C# 3.0, it is possible to declare an Auto Property.
• The field can be omitted.

    public class Person {

        public int ID { get; } //read-only auto-property

        public string Name { get; set; }

        public int IQ { set; } //write-only auto-property
    }

                                                                17
                     236703 - Object-oriented Programming        17
Static Properties

public struct HarryPotterBook {
  static private int count;

    // static constructor
    static HarryPotterBook() {
        count = she_wrote_it() ? 7 : 6;
    }

    // read-only static property
    static public int Count {
      get { return count; }
    }
    …
}

                                                  18
           236703 - Object-oriented Programming    18
Using Delegates
Classic Example:
                when the room gets warmer
                   The AC should turn on,
           and when it gets cooler, it should turn off.

• Delegation: Software design and real-life:
   • Increasing Encapsulation by separating event and feedback
   • Which object “was there first?”
   • Scalability issues

                                                            19
                                                  19
Delegates
• A type that references a method (similar to C++
  function pointer)
• Supply type safety: only a method that matches* the
  delegate's signature (return type and parameters) can
  be assigned to the delegate
• Allow methods to be used as first class objects (e.g.
  passed as parameters)
• Multicast (multiple methods can be assigned to a
  single delegate)
• Delegates reference to a method, and thus associated
  with an instance (with the exception of static
  methods).
• Support anonymous methods (later in this lesson)
                                                          20
                236703 - Object-oriented   20
Delegate Type Hierarchy
using System;
using System.Reflection;
delegate object MyDelegateType(Type o);
public static class DelegateTypeHierarchy {
  private static string DelFunc(Type t) { as before... }
  private static void Ancestory(object o){ as before… }
  public static void Main() {
    Ancestory(new MyDelegateType(DelFunc));
  }
}
                      MyDelegateType inherits from System.MulticastDelegate
                      System.MulticastDelegate inherits from System.Delegate
                      System.Delegate inherits from System.Object
                      System.Object inherits from null

                                                                               21
                     236703 - Object-oriented               21
Using Delegates
• There are three steps in defining and using delegates:

           declaration assignment      invocation

                                                           22
                                                 22
Using Delegates
Step 1: Declaring a delegate – The observable:
   [modifiers] delegate return_type identifier([parameter_types])

   //Declare a delegate type
   //Can be put inside the class to reduce namespace pollution
   public delegate void TemperatureChangeHandler(int c);

   public partial class TemperatureSensor {
       //Declare a delegate variable
       public TemperatureChangeHandler OnTempChanged;
   }

                                                                    23
                     236703 - Object-oriented            23
Using Delegates
The observer(s):

public class SmartAirConditioner {
    public void ConnectToSensor(TemperatureSensor ts) {
        //Assign a delegate – start observing ts
        ts.OnTempChanged += TemperatureChangedCallback;
    }
    public void TemperatureChangedCallback(int t) {
        if(t > 24 && IsOff) StartCooling();
        else if(t < 18 && IsOff) StartWarming();
        else TurnOff();
    }
    public void StartCooling(){… IsOff = false; …}
    public void StartWarming(){… IsOff = false; …}
    public void TurnOff(){ IsOff = true; … }
}

                                                          24
                   236703 - Object-oriented      24
Using Delegates
Step 2: Assigning a delegate to a variable
   – Assign a delegate using = operator
   – Add a delegate using += operator
       • has a default implementation, but the programmer can provide his own add.
   – Remove a delegate using -= operator
       • has a default implementation, but the programmer can provide his own
         remove.

public static void Main(string[] args)
{
   var ts = new TemperatureSensor();
   ...
   var ac = new SmartAirConditioner();
   ac.ConnectToSensor(ts);
}                           public void ConnectToSensor(TemperatureSensor       ts)
                                  {
                                                                                 25
                                       ts.OnTempChanged += TemperatureChangedCallback;
                     236703 - Object-oriented
                               }                              25
Using Delegates
Step 3: Invoking the delegate – The observable:
  public partial class TemperatureSensor
  {
      //This method invoked by some hardware…(for this example)
      void TemperatureChanged(int t)
      {
           if (null != OnTempChanged)
             OnTempChanged(t); //Invoke all delegates
      }
  }

                                                                  26
                     236703 - Object-oriented            26
Problems?
• Consider the following code samples:
public void ConnectToSensor(TemperatureSensor ts)
{
   ts.OnTempChanged = TemperatureChangedCallback;
                                         //null is even worse!
}                       Problem 1

public void ConnectToSensor(TemperatureSensor ts)
{
   ts.OnTempChanged(42);
                             Problem 2
}

              public static void Main() {
                 var ts = new TemperatureSensor();
                 ...
                 var ac = new SmartAirConditioner();
                 ac.ConnectToSensor(ts);
                                                                 27
              }
                236703 - Object-oriented               27
The event keyword
• The event keyword can be associated with a field of type
  delegate
• An event can only appear on the lhs of += or -= except
  when used from the defining class
   – Excluding derived classes as well
   – The defining class treats it like any other delegate (assign it with
     =, invoke it, etc.)
   – Event are like properties, which have two actions: add, remove.
• Events may appear in interfaces!

           Our Example: royal social conduct
               If King is happy: notify all men in the kingdom
               If King is ill: notify noblemen only.

                                                                       28
                    236703 - Object-oriented             28
King, Nobleman and Citizens
                                                           Kingdom
                            Man                            namespace
           Life
           static          abstract
                                                 Notify
                                                delegate

         Citizen        Nobleman            King           State
           sealed         concrete         concrete        enum

• Name: every man has a name
• Title: every man has a title, based on his status and name
   – Realized by method ToString()
• Service: every man can be set to service any number of kings.
   – Method service(King k) in class Man                               29
                    236703 - Object-oriented          29
Delegate Notify
• Type definition: A reference to a method (to be called when a king changes his
   state)
                  namespace Kingdom {
                    delegate object Notify(King k);                     Notify
                    …                                                  delegate
                  }

• Simple (uninteresting) use:
            void foo(King k){
              Notify bar; // A delegate variable of type Notify
              bar = FunctionDescriptor;
              …
              object o = bar(k); // Invoke FunctionDescriptor
            }

• A more interesting use:
              class Foo {
                event Notify baz; // An event of type Notify
                public void foo(King k) {
                  baz += FunctionDescriptor;
                  …
                  baz(k); // Invoke FunctionDescriptor
                } }                                                               30
                            236703 - Object-oriented              30
Delegates and Events
• Delegate type definition:
      namespace Kingdom {
          delegate object Notify(King k);
          …
      }

• Event definition:
      namespace Kingdom {
          class King : Man {
          public event Notify
        OnKingIllness, OnKingHappiness;
          …
      }                          Why were OnKingIllness,
                             OnKingHappiness declared as events?

                                                                   31
                    236703 - Object-oriented           31
Class King and Enum State
namespace Kingdom {
   …
enum State { Happy, Ill };
…
class King : Man {
  public State state;
  public King(String name): base(name){state = State.Ill;}                                              State
  sealed override public string ToString() {                                                            enum
     return "His Majesty, King " + Name;
  }
  // events for those interested in the King's being.
  public event Notify OnKingIllness, OnKingHappiness;
  //returns last listener’s return value – use GetInvocationList() to iterate the registered callbacks
  public object BeIll() {
       state = State.Ill;
       return OnKingIllness!= null ? OnKingIllness(this): null;
   }                                                                                                 King
  //returns last listener’s return value - use GetInvocationList() to iterate the registered callbacks
  public object BeHappy() {                                                                            concrete
       state = State.Happy;
       return OnKingHappiness!= null ? OnKingHappiness(this): null;
  }
}

                                                                                                         32
                        236703 - Object-oriented                                32
Class Man

namespace Kingdom {
  abstract class Man {
    protected readonly String Name;
    public Man(String name) { Name = name; }
    abstract override public String ToString();

        // Every man is happy when a King he serves is happy.
        virtual public void Serve(King k) {
           k.OnKingHappiness += Happy;
        }                                                          Man
        public Man Happy(Man m) {                                 abstract
           Console.WriteLine(this + “ is happy to hear that " +
                               m + " is happy.“)
           return this;
        }
    }
    …
}

                                                                        33
                  236703 - Object-oriented            33
Registration of an Actual Delegate
• Actual Delegate: a method for notification
                namespace Kingdom {
                  abstract class Man { …
                    public Man Happy(Man m) {
                      Console.WriteLine(this +
                             “ is happy to hear that " +
                                    m + " is happy.“)
                      return this;
                    }
                  … }

• Register a delegate: with += operator
               namespace Kingdom {
                 abstract class Man {
                   …
                   virtual public void Serve(King k) {
                     k.OnKingHappiness += Happy;
                   }
                 …}
                                                                34
                     236703 - Object-oriented              34
Classes Citizen and Nobleman
 namespace Kingdom {…
      sealed class Citizen : Man {
     public Citizen(string name) : base(name) { }
     override public string ToString() {
       return "Citizen " + Name;
     }                                                Citizen
  }                                                    sealed
  class Nobleman : Man {
     public Nobleman(string name) : base(name) { }
     override public string ToString() {
       return "Nobleman " + Name;
     }
     public Nobleman Ill(Man m) {
       Console.WriteLine(this +
             " is sorry to hear that " + m
                  + " is ill.");
          return this;
     }
     override public void Serve(King k) {
                                                     Nobleman
       base.Serve(k);                                 concrete
       k.OnKingIllness += Ill;
     }
  }
  …{

                                                                35
          236703 - Object-oriented            35
Main Application
static class Life {
  static void Main() {
    King R = new King("Richard");        Life
    King G = new King("George");
    Citizen a = new Citizen("Al");       static
    Citizen b = new Citizen("Bob");
    Nobleman v = new Nobleman("Virgil");
    a.Serve(R);                                    Richard
    b.Serve(R); b.Serve(G);                                       George
    v.Serve(R);
    G.Serve(R);

        R.beIll();
        R.beHappy();
        Console.WriteLine("----");                Al
        G.beIll();
        G.beHappy();                                                Virgil
        Console.WriteLine("----");                          Bob
    }
}

                                                                     36
                    236703 - Object-oriented           36
Output
                                     Scenario
                                      1. King Richard becomes ill
 Richard                              2. King Richard becomes happy
                  George
                                      3. King George becomes ill
                                      4. King George becomes happy
                                     Remember, every man is happy when a king
Al                                   he serves is happy, but only a Noblemen is to
                      Virgil         be notified when his king is ill.
       Bob
     Noblemen Virgil is sorry to hear that His Majesty, King Richard is ill.
     Citizen Al is happy to hear that His Majesty, King Richard is happy.
     Citizen Bob is happy to hear that His Majesty, King Richard is happy.
     Noblemen Virgil is happy to hear that His Majesty, King Richard is happy.
     His Majesty, King George is happy to hear that His Majesty, King Richard is happy.
     ----
     Citizen Bob is happy to hear that His Majesty, King George is happy.
     ----
                                                                                          37
                        236703 - Object-oriented                            37
Indexers
•   Purpose: Implement array access with methods
•   Similar to properties (though no static indexers)
     – Syntax: modifiers returnType this[IndexType pos]
     – Variations:
          • multi-parameters indexers
          • read-only, write-only and read-write indexers
          • overloaded indexers

class List {
  …
  private Node Nth(Node n, uint d) {
    if (n == null) throw new Exception("out of range");
    return d == 0 ? n : Nth(n.Next, d-1);
  }
  public object this[uint i] { // indexer using ordinal position
    get { return Nth(first, i).Data; }
    set { Nth(first, i).Data = value; }
  }
}
                                                               39
                     236703 - Object-oriented Programming       39
Using the Indexer
class List {
 static void Main() {
   const uint n = 5;
   List sq = new List(n);
   for (uint i = 0; i < n; i++)
     sq[i] = i * i;
   for (uint i = 0; i < n; i++)
     Console.WriteLine(i + "^2 = " + sq[i]);
 }
}
                                                      0^2   =   0
                                                      1^2   =   1
                                                      2^2   =   4
                                                      3^2   =   9
                                                      4^2   =   16
                                                                     40
               236703 - Object-oriented Programming                   40
Extension methods
• Extension methods are a special kind of static method
• Extension methods allow "adding" methods to existing types without
  modifying the original type
   public static class DateTimeExtention {
        public static DateTime ToIsraeliTime(this DateTime p_dt){
             return p_dt.ToUniversalTime().AddHours(3);
        }
   }

  DateTime utc = DateTime.UtcNow;
  Assert.AreEqual(utc.AddHours(3),utc.ToIsraeliTime());
  DateTime now = DateTime.Now;
  Assert.AreEqual(now, now.ToIsraeliTime());               // Yay! The test passes.
  So why do we need ToIsraeliTime() extension anyway? Why not use DateTime.Now?

                                                                                      42
                          236703 - Object-oriented Programming
Rules for the extension methods
• The first parameter specifies which type the method operates on
    – the parameter is preceded by this modifier
• Extension methods can be used only when the namespace in which the
  methods are defined is explicitly imported with a using directive.
• Extension methods cannot access private variables in the type they are
  extending
• Extension methods can extend a class or interface
• An extension method with the same name and signature as an interface
  or class method will never be called.
    – At compile time, extension methods always have lower priority than
      instance methods defined in the type itself

                                                                            43
                     236703 - Object-oriented Programming              43
Anonymous Methods
• Anonymous methods represent a way to pass a code block as a delegate
  parameter.
  delegate void Printer(string s);
  class AnonymousMethods{
    static void Main() {
      Printer p += delegate(string j) { Console.WriteLine(j);};
      p("The delegate using the anonymous method is called.");
      p = new Printer(AnonymousMethods.DoWork);
      p("The delegate using the named method is called.");
    }
    static void DoWork(string k) {
      Console.WriteLine(k);
    }
  }

           The delegate using the anonymous method is called.
           The delegate using the named method is called.                44
                                                       44
Anonymous Methods (2)
delegate void Printer2();

class AnonymousMethods {
  static void Main(string[] args) {
    string j = "The delegate with local variable is called.";
    Printer2 p2 = delegate() {Console.WriteLine(j);};
    p2();
}

                The delegate with local variable is called.

Note: C# 7.0 introduces Inner-Methods…

                                                                45
                                                          45
Lambda Expressions
• A lambda expressions is an anonymous function, that use the lambda
  operator =>.
    – The left side of the lambda operator specifies the input parameters (if any)
    – The right side holds the expression or statement block

 delegate void Printer(string s);

 class LambdaExpressions{
   static void Main(string[] args) {
     Printer p = j => Console.WriteLine(j);
     p("The delegate using the anonymous method is called.");
   }
 }

              The delegate using the anonymous method is called.

                                                                                     46
                                                                        46
Anonymous and dynamic Types
class MyClass {
   public static dynamic Foo(){
       return new {Field1 = "Value1“, Field2 = 69};
   }
}

static dynamic what???

 Foo() is a static-method of MyClass, that returns dynamic (since C# 4.0) type
              (methods don’t have to be static to return dynamic type)

• dynamic object is an object whose operations will be resolved at run-time.
• Anonymous Types cannot have methods or fields. Properties Only!
• Why not use Object or Generics then? It has same features, no?
      • Object &  are resolved at compile-time!
            • void Print(Object d) {Console.WriteLine(d.Field1);} won’t compile
            • void Print(T d) {Console.WriteLine(d.Field1);} won’t compile
            • void Print(dynamic d) {Console.WriteLine(d.Field1);} will throw a
              RuntimeException when called if d has no Field1 property.           47
                                                                   47
Anonymous Types
Benefits of Anonymous Types
• The best way to obtain “non-types” capabilities
      • as in JavaScript, Python
• Saves time and doesn’t pollute the namespace
• For example:
  public static string ToJson(object o) Can use (dynamic o) as well
  {
      return string.Format("{{" + Environment.NewLine + "{0}" +
                                   Environment.NewLine + "}}",
               string.Join(Environment.NewLine,
                         o.GetType()
                          .GetProperties().ToList()
                          .ConvertAll(p =>
                             $"\"{p.Name}\" : \" {p.GetValue(o)} \"")));
  }

                                                                           48
                                                        48
Anonymous Types
Benefits of Anonymous Types
• The best way to obtain “non-types” capabilities
      • as in JavaScript, Python
• Saves time and doesn’t pollute the namespace
• For example:
class Person                           Console.WriteLine(
{                                          ToJson(
 public string FirstName {get; set;}            new {
 public string LastName {get; set;}                   FirstName = “Roy”,
 public int Grade {get; set;}                         LastName = “Moshe”,
}                                                     Grade = 95
Person p = new Person();                            } );
p.FirstName = “Roy”;
p.LastName = “Moshe”;
p.Grade = 95;
Console.WriteLine(ToJson(p));
                                                                            49
                                                         49
Summary – C# Unique Features
• Properties: implement fields with functions
    – Conforms to Eiffel Principle of Uniform Reference.
• Delegates: type safe function pointers
    – Events: list of delegates.
• Static classes
• Seamless integration of value semantics
    – Including nullable values.

C# 7.0 is out: https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-
csharp-7-0/

                                                                              50
                       236703 - Object-oriented              50
Let’s play some poker

                        51
You can also read