DNP1 – Session 2
More C#
The plan
• Inheritance, interfaces
• Method overriding, virtual & override
• Delegates
• Lambda expressions
• Predicates
• Nullable
Inheritance
• A class can extend another class
• A class can extend a maximum of one class
• A class can implement any number of interfaces
Just
like
in Ja
va
Inheritance Separated by
colon
Java: super
Derived class
Super class C#: base
Constructor
in sub-class
Call to super class
constructor, with
name argument
With interfaces class, interface1, interface2, interface3
Interfaces,
Super class Interfaces
notice initial ‘I’
Forgot about inheritance?
Method overriding in inheritance
• What’s this?
• C# has something extra here
Method overriding
Use when you
expect/allow this
method to be
overridden
By default, you
should always use
this, when you
override
Use when you
intentionally want to
override functionality
of the super class.
Virtual and override
If I remove virtual from BaseClass,
compiler complains.
If I then remove override from
DerivedClass, I get a warning, telling me
to use ‘new’
Virtual and override
Abstract classes, similar to java
If a method is declared abstract, the
class must also be abstract.
‘abstract’ indicates this method body
is missing, and must be implemented
in a sub-class
What’s the problem here?
Interfaces Like java, just without access
modifier. Everything is
implicitly public
Naming Convention
All interfaces in .NET start with an I
Interfaces
An interface can extend
multiple interfaces
The plan
• Inheritance, interfaces
• Method overriding, virtual & override
• Delegates
• Lambda expressions
• Predicates
• Nullable
Delegates
• Remember the observer pattern?
• C# provides this functionality for us.
• A delegate is a reference to one or more methods. When the delegate is
invoked, all referenced methods are called.
• Other uses too, e.g. pass a method as a parameter to another method.
• Loose coupling, wuhu!
How to use a method as argument
Action is a no-argument
method-reference
This argument is a method,
which takes a string as
argument
How to use a method as argument
How to use a method as argument
Create
new
instance
Create
new
instance
How to use a method as argument Result: Hello world is
printed to console
Calling this
method
With this
method as
argument
How to use a method as argument
Hello world
Hello students
Hello moon
Delegates
• Delegate is the “super class”
• Action is a specific type of delegate
• Return type is void
• It takes arguments according to the type parameters: <string, int, Person, …>
• Func<arg1, arg2, …, argX, return-type>
• Also a specific type of delegate
• Last type parameter is the return type, i.e. not void.
• First type parameters are arguments.
• We can define our own delegates.
Syntax to define a delegate
Defining my own delegate type:
MyDelegate
Have an instance of this type
Invoke the delegate (i.e. notify listeners)
What am I
doing here? If(OnTimeChange != null) {
OnTimeChange.Invoke(s);
}
Adding methods to the delegate
Instance of the
class with the
delegate
Adding a
method to the
delegate
Remove method Multiple
from the Signature must methods can be
delegate match the added
delegate’s
Delegates
• The delegate is used to define a new type.
• Action<T> and Func<T,R> already exists:
Is a delegate, with one argument of
type ‘string’. Return type void.
Multiple arguments can be used if
needed: Action<int, string, Person>
Is a delegate, with one argument of
type ‘string’. Return type int.
Multiple arguments can be used if
needed.
If multiple methods are in the
Func, then only the result of the
last method is return
Traffic light example
What’s up with
?
Alternatives:
Running the example
• An Action or Delegate is a list of methods
• Invoking the Action/Func/Delegate means to call all methods in the list
The plan
• Inheritance, interfaces
• Method overriding, virtual & override
• Delegates
• Lambda expressions
• Predicates
• Nullable
Lambda expression
• It’s a syntax to create delegates.
• It is an anonymous function
Read more here
• Examples:
Lambda expression No
arguments
private void Print() public void RunExample()
{ {
Console.WriteLine("Hello world"); Print();
} Action p = () => Console.WriteLine("Hello World");
private void Print(string s) p.Invoke();
{ }
Console.WriteLine(s); Calling my anonymous
} method, p
Lambda expression
public void RunExample()
private void Print()
{
{
Print();
Console.WriteLine("Hello world");
Action p = () => Console.WriteLine("Hello World");
}
p.Invoke();
private void Print(string s)
{
Print("Goodbye world");
Console.WriteLine(s);
}
Action<string> p1 =
(argument) => Console.WriteLine(argument);
p1.Invoke("Goodbye world");
}
Lambda • Creating a variable of type Func
Lambda example
Predicates (a method that defines a criteria, returns bool)
public void Run() Predicate public class BookRepository
{ {
List<Book> books = new BookRepository().GetBooks(); public List<Book> GetBooks()
{
List<Book> cheapBooks = books.FindAll(CheaperThan50Dollars); return new()
{
List<Book> alsoCheap = books.FindAll(book => book.Price < 50); new Book() {Title = "First", Price = 42},
} new Book() {Title = "Second", Price = 1337},
new Book() {Title = "Third", Price = 12.34m},
private bool CheaperThan50Dollars(Book obj) new Book() {Title = "Fourth", Price = 65.95m}
{ };
return obj.Price < 50; }
} Same result: Find }
all books, where
given a book, the
books price is less
than 50
Predicates (a method that defines a criteria, returns bool)
books.FindAll(b => b.Price < 10).FindAll(b => b.Title.Equals(“First”));
More about predicates
Put carret at parameter, press [CTRL]+P
public void Run() public class BookRepository
{ {
List<Book> books = new BookRepository().GetBooks(); public List<Book> GetBooks()
{
List<Book> cheapBooks = books.FindAll(CheaperThan50Dollars); return new()
{
List<Book> alsoCheap = books.FindAll(book => book.Price < 50); new Book() {Title = "First", Price = 42},
} new Book() {Title = "Second", Price = 1337},
new Book() {Title = "Third", Price = 12.34m},
private bool CheaperThan50Dollars(Book obj) new Book() {Title = "Fourth", Price = 65.95m}
{ };
return obj.Price < 50; }
} }
}
The plan
• Inheritance, interfaces
• Method overriding, virtual & override
• Delegates
• Lambda expressions
• Predicates
• Nullable
Nullables
• This is a compile time feature, by default it is turned on
• The purpose is to avoid null reference exceptions and checking for null
• Compiler will warn you, if you have a variable, which may be null
• We can indicate that variables may be null by appending ”?”.
• This is good practice
Nullables
public string? Description { get; set; }
Assuming you allow Description to be null
Nullables Shut the compiler up
• Alternatively:
• Instantiate the property public string Description { get; set; } = null!;
• Or create a constructor
• This results in the property
never being null public string Description { get; set; } = "";
Not always
possible with
other types.
public string Description { get; set; }
public Todo(string description)
{
Usually a good
Description = description;
appraoch
}
Nullables
Method returns null if no Todo matches
Indicates this variable may contain null
Todo? todoWithId7 = todos.FirstOrDefault(todo => todo.Id == 7);
Nullables
• Sometimes the compiler will warn you, but you want to shut it up, because
you know what you’re doing.
Suppress null
• We use ”!” warning
public string Description { get; set; } = null!;
Todo? todoWithId7 = todos.FirstOrDefault(todo => todo.Id == 7);
Todo todoWithId7Again = todos.FirstOrDefault(todo => todo.Id == 7)!;
Not a great e
xample, thou
gh
The point?
private void ValidateUserName(string username) private void ValidateUserName(string? username)
{ {
if (username.Length < 3) if (username == null)
{ {
throw new Exception("Could you not"); throw new Exception("No no");
} }
} if (username.Length < 3)
{
throw new Exception("Could you not");
}
}
The compiler will warn you.
But you can still ignore that warning and mess up.
Nullables
• What are the possible values of Boolean?
• Sometimes it would be nice if a Boolean could also be null
bool? b = null;
• Can be done for all simple types and objects; append with ? to allow the
variable value to be null
Exercises