Object Oriented Concepts – C#
Object Oriented Concepts – C#
Q
Q
Agenda
Agenda
Review Object-Oriented Concepts
Review Object-Oriented Concepts
Interfaces
Interfaces
Classes and Structs
Classes and Structs
Delegates
Delegates
Events
Events
Review
Review
Key Object-Oriented Concepts
Key Object-Oriented Concepts
Inheritance
Inheritance
The “is a” relationship
The “is a” relationship
Types are arranged in a hierarchy
Types are arranged in a hierarchy
Called base/derived or superclass/subclass
Called base/derived or superclass/subclass
Accord Corvette
Car Truck Plane Boat
Vehicle
Accelerate()
Decelerate()
TakeOff()
Land()
OpenTrunk()
VIN
Review
Review
Key Object-Oriented Concepts
Key Object-Oriented Concepts
Polymorphism
Polymorphism
The ability to perform an operation on an object without knowing
The ability to perform an operation on an object without knowing
the precise type of the object
the precise type of the object
Lets “old” code call “new” code
Lets “old” code call “new” code
void Poly(object o) {
Console.WriteLine(o.ToString());
}
Poly(42);
Poly(“abcd”);
Poly(12.345678901234m);
Poly(new Point(23,45));
Poly(new PurchaseOrder(“PO11235811”));
Agenda
Agenda
Review Object-Oriented Concepts
Review Object-Oriented Concepts
Interfaces
Interfaces
Classes and Structs
Classes and Structs
Delegates
Delegates
Events
Events
Interfaces
Interfaces
An interface defines a contract
An interface defines a contract
An interface is a type
An interface is a type
Can declare variables of that type
Can declare variables of that type
However, you cannot directly instantiate an interface
However, you cannot directly instantiate an interface
Includes methods, properties, indexers, events
Includes methods, properties, indexers, events
Any class or struct implementing an interface must support all parts of
Any class or struct implementing an interface must support all parts of
the contract
the contract
Interfaces provide no implementation
Interfaces provide no implementation
When a class or struct implements an interface it must provide the
When a class or struct implements an interface it must provide the
implementations for all members of the interface
implementations for all members of the interface
Interfaces provide polymorphism
Interfaces provide polymorphism
Many classes and structs may implement a particular interface
Many classes and structs may implement a particular interface
public interface IDisposable {
void Dispose();
}
public class TextBox : IDisposable {
public void Dispose() { ... }
}
public class Car : IDisposable {
public void Dispose() { ... }
}
Interfaces
Interfaces
Example
Example
void PolyDispose(IDisposable id) {
id.Dispose();
} TextBox tb = new TextBox();
PolyDispose(tb);
Car c = new Car();
PolyDispose(c);
Interfaces
Interfaces
Casting
Casting
A class that implements an interface can be cast
A class that implements an interface can be cast
(converted) to any of those interfaces
(converted) to any of those interfaces
public interface IDisposable {
}
public interface IEnumerable {
}
public class ListBox : IDisposable, IEnumerable {
}
ListBox lb = new ListBox();
IDisposable id = (IDisposable)lb;
IEnumerable ie = (IEnumerable)lb;
interface ITextBox {
void SetText(string s);
}
interface IListBox {
void SetItems(string[] items);
}
interface IComboBox: ITextBox, IListBox {
}
Interfaces
Interfaces
Multiple Inheritance
Multiple Inheritance
Interfaces can inherit from multiple interfaces
Interfaces can inherit from multiple interfaces
Classes and structs can inherit from
Classes and structs can inherit from
multiple interfaces
multiple interfaces
Agenda
Agenda
Review Object-Oriented Concepts
Review Object-Oriented Concepts
Interfaces
Interfaces
Classes and Structs
Classes and Structs
Delegates
Delegates
Events
Events
Classes and Structs
Classes and Structs
Similarities
Similarities
Both are user-defined types
Both are user-defined types
Both can contain
Both can contain
Data
Data
Fields, constants, events, arrays
Fields, constants, events, arrays
Functions
Functions
Methods, properties, indexers, operators
Methods, properties, indexers, operators
Constructors, finalizers
Constructors, finalizers
Type definitions
Type definitions
Classes, structs, enums, interfaces, delegates
Classes, structs, enums, interfaces, delegates
Both can implement multiple interfaces
Both can implement multiple interfaces
Both are instantiated with
Both are instantiated with new
new operator
operator
Class
Class Struct
Struct
Reference type
Reference type Value type
Value type
Can inherit from any
Can inherit from any
non-sealed reference class
non-sealed reference class
No inheritance
No inheritance
(inherits only from
(inherits only from System.ValueType
System.ValueType)
)
Can have a finalizer
Can have a finalizer No finalizer
No finalizer
Can have user-defined
Can have user-defined
parameterless constructor
parameterless constructor No user-defined parameterless constructor
No user-defined parameterless constructor
Classes and Structs
Classes and Structs
Differences
Differences
C++ Struct
C++ Struct C# Struct
C# Struct
Same as C++ class, but all members
Same as C++ class, but all members
are
are public
public User-defined value type
User-defined value type
Can be allocated on the heap,
Can be allocated on the heap,
on the stack or as a member
on the stack or as a member
(can be used as value or reference), just
(can be used as value or reference), just
like C++ class
like C++ class
Always allocated on the stack or
Always allocated on the stack or
as a member
as a member
Members are always
Members are always public
public Members can be
Members can be public
public,
, internal
internal
or
or private
private
Classes
Classes and Structs
and Structs
C# Structs vs. C++ Structs
C# Structs vs. C++ Structs
Very different from C++ struct
Very different from C++ struct
public class Car : Vehicle {
public enum Make { GM, Honda, BMW }
Make make;
string vid;
Point location;
Car(Make m, string vid; Point loc) {
this.make = m;
this.vid = vid;
this.location = loc;
}
public void Drive() {
Console.WriteLine(“vroom”); }
}
Car c =
new Car(Car.Make.BMW,
“JF3559QT98”,
new Point(3,7));
c.Drive();
Classes and Structs
Classes and Structs
Class
Class
public struct Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int X { get { return x; }
set { x = value; } }
public int Y { get { return y; }
set { y = value; } }
}
Point p = new Point(2,5);
p.X += 100;
int px = p.X; // px = 102
Classes and Structs
Classes and Structs
Struct
Struct
Classes
Classes and Structs
and Structs
Static vs. Instance Members
Static vs. Instance Members
By default, members are per instance
By default, members are per instance
Each instance gets its own fields
Each instance gets its own fields
Methods apply to a specific instance
Methods apply to a specific instance
Static members are per type
Static members are per type
Static methods can’t access instance data
Static methods can’t access instance data
No
No this
this variable in static methods
variable in static methods
Don’t abuse static members
Don’t abuse static members
They are essentially object-oriented
They are essentially object-oriented
global data and global functions
global data and global functions
Classes and Structs
Classes and Structs
Access Modifiers
Access Modifiers
Access modifiers specify who can use a type
Access modifiers specify who can use a type
or a member
or a member
Access modifiers control encapsulation
Access modifiers control encapsulation
Top-level types (those directly in a namespace) can be
Top-level types (those directly in a namespace) can be
public
public or
or internal
internal
Class members can be
Class members can be public
public,
, private
private,
, protected
protected,
,
internal
internal, or
, or
protected internal
protected internal
Struct members can be
Struct members can be public
public,
, private
private or
or internal
internal
If the access
If the access
modifier is
modifier is
Then a member defined in type T and
Then a member defined in type T and
assembly A is accessible
assembly A is accessible
public
public to everyone
to everyone
private
private within T only (the default)
within T only (the default)
protected
protected to T or types derived from T
to T or types derived from T
internal
internal to types within A
to types within A
protected internal
protected internal to T or types derived from T
to T or types derived from T
or to types within A
or to types within A
Classes and Structs
Classes and Structs
Access Modifiers
Access Modifiers
Classes and Structs
Classes and Structs
Abstract Classes
Abstract Classes
An abstract class is one that cannot be instantiated
An abstract class is one that cannot be instantiated
Intended to be used as a base class
Intended to be used as a base class
May contain abstract and non-abstract function members
May contain abstract and non-abstract function members
Similar to an interface
Similar to an interface
Cannot be sealed
Cannot be sealed
Classes and Structs
Classes and Structs
Sealed Classes
Sealed Classes
A sealed class is one that cannot be used as a base class
A sealed class is one that cannot be used as a base class
Sealed classes can’t be abstract
Sealed classes can’t be abstract
All structs are implicitly sealed
All structs are implicitly sealed
System.String is sealed
System.String is sealed
Why seal a class?
Why seal a class?
To prevent unintended derivation
To prevent unintended derivation
Code optimization
Code optimization
Virtual function calls can be resolved at compile-time
Virtual function calls can be resolved at compile-time
class Person
{
string name;
public Person(string name)
{
this.name = name;
}
public void Introduce(Person p)
{
if (p != this)
Console.WriteLine(“Hi, I’m “ + name);
}
}
Classes and Structs
Classes and Structs
this
this
The
The this
this keyword is a predefined variable available in
keyword is a predefined variable available in
non-static function members
non-static function members
Used to access data and function members unambiguously
Used to access data and function members unambiguously
class Shape
{
int x, y;
public override string ToString()
{
return "x=" + x + ",y=" + y;
}
}
class Circle : Shape
{
int r;
public override string ToString()
{
return base.ToString() + ",r=" + r;
}
}
Classes and Structs
Classes and Structs
base
base
The
The base
base keyword is used to access class members that
keyword is used to access class members that
are hidden by similarly named members of the current
are hidden by similarly named members of the current
class
class
public class MyClass
{
public const string version = “1.0.0”;
public const string s1 = “abc” + “def”;
public const int i3 = 1 + 2;
public const double PI_I3 = i3 * Math.PI;
public const double s = Math.Sin(Math.PI); //ERROR
...
}
Classes and Structs
Classes and Structs
Constants
Constants
A constant is a data member that is evaluated at
A constant is a data member that is evaluated at
compile-time and is implicitly static (per type)
compile-time and is implicitly static (per type)
e.g.
e.g. Math.PI
Math.PI
Classes and Structs
Classes and Structs
Fields
Fields
A field is a member variable
A field is a member variable
Holds data for a class or struct
Holds data for a class or struct
Can hold:
Can hold:
a reference type (e.g. class instance),
a reference type (e.g. class instance),
a value type (e.g. a struct instance), or
a value type (e.g. a struct instance), or
an array of class or struct instances
an array of class or struct instances
(an array is actually a reference)
(an array is actually a reference)
Classes and Structs
Classes and Structs
Readonly Fields
Readonly Fields
Similar to a const, but is initialized at
Similar to a const, but is initialized at
run-time in its declaration or in a constructor
run-time in its declaration or in a constructor
Once initialized, it cannot be modified
Once initialized, it cannot be modified
Differs from a constant
Differs from a constant
Initialized at run-time (vs. compile-time)
Initialized at run-time (vs. compile-time)
Don’t have to re-compile clients
Don’t have to re-compile clients
Can be static or per-instance
Can be static or per-instance
public class MyClass {
public static readonly double d1 = Math.Sin(Math.PI);
public readonly string s1;
public MyClass(string s) { s1 = s; } }
public class Button: Control
{
private string _caption;
public string caption
{
get { return _caption; }
set { _caption = value;
Repaint(); }
}
}
Button b = new Button();
b.caption = "OK";
String s = b.caption;
Classes and Structs
Classes and Structs
Properties
Properties
A property is a virtual field
A property is a virtual field
Looks like a field, but is implemented with code
Looks like a field, but is implemented with code
public class Person
public class Person
{
{
private int age;
private int age;
public int Age {
public int Age {
get { return age; }
get { return age; }
set { age =
set { age = value
value;
;
Console.WriteLine(age);
Console.WriteLine(age);
}
}
}
}
}
}
Person p = new Person();
Person p = new Person();
p.Age = 27;
p.Age = 27;
p.Age++;
p.Age++;
Properties
Properties
Access to private fields normally requires accessors and
Access to private fields normally requires accessors and
mutators
mutators
Properties allow access to private fields as if they were
Properties allow access to private fields as if they were
public
public
Person p = new Person();
Person p = new Person();
p.setAge(27);
p.setAge(27);
p.setAge(p.getAge() + 1);
p.setAge(p.getAge() + 1);
instead of:
instead of:
Property
Property
C#
C#
Other
Other
Classes and Structs
Classes and Structs
Properties
Properties
Properties can be:
Properties can be:
Read-only (implement only
Read-only (implement only get
get)
)
Not the same as a
Not the same as a readonly
readonly field
field
Write-only (implement only
Write-only (implement only set
set)
)
Read/write (implement both
Read/write (implement both get
get and
and set
set)
)
Indexers
Indexers
Index an object as if it were an array
Index an object as if it were an array
public class numbers
public class numbers
{
{
private int[3] nums;
private int[3] nums;
public int this[int index]
public int this[int index]
{
{
get { return nums[index]; }
get { return nums[index]; }
set { nums[index] = value; }
set { nums[index] = value; }
}
}
}
}
Numbers Num = new Numbers
Numbers Num = new Numbers()
();
;
Num[0] = 5;
Num[0] = 5;
int Val = Num[0];
int Val = Num[0];
Numbers Num = new Numbers
Numbers Num = new Numbers()
();
;
Num.Set_Nums(0,5);
Num.Set_Nums(0,5);
int Val = Num.Get_Nums(0);
int Val = Num.Get_Nums(0);
instead of:
instead of:
Indexer
Indexer
C#
C#
Other
Other
public class ListBox: Control
{
private string[] _items;
public string this[int index]
{
get { return _items[index]; }
set { _items[index] = value;
Repaint(); }
}
} ListBox listBox = new ListBox();
listBox[0] = "hello";
Console.WriteLine(listBox[0]);
Classes and Structs
Classes and Structs
Indexers
Indexers
An indexer lets an instance behave as a virtual array
An indexer lets an instance behave as a virtual array
Can be overloaded
Can be overloaded (e.g. index by
(e.g. index by int
int and by
and by string
string)
)
Can be
Can be
read-only,
read-only,
write-only,
write-only,
or read/write
or read/write
Classes and Structs
Classes and Structs
Methods
Methods
All code executes in a method
All code executes in a method
Constructors, finalizers and operators are special types of
Constructors, finalizers and operators are special types of
methods
methods
Properties and indexers are implemented with get/set methods
Properties and indexers are implemented with get/set methods
Methods have argument lists
Methods have argument lists
Methods contain statements
Methods contain statements
Methods can return a value
Methods can return a value
Only if return type is not void
Only if return type is not void
Classes and Structs
Classes and Structs
Method Argument Passing
Method Argument Passing
By default, data is passed by value
By default, data is passed by value
A copy of the data is created and passed to the method
A copy of the data is created and passed to the method
For value types that are passed by value, variables
For value types that are passed by value, variables
cannot be modified by a method call
cannot be modified by a method call
For reference types that are passed by value, the instance
For reference types that are passed by value, the instance
can be modified by a method call, but the variable itself
can be modified by a method call, but the variable itself
cannot be modified by a method call
cannot be modified by a method call
void RefFunction(ref int p) {
p++;
} int x = 10;
RefFunction(ref x);
// x is now 11
Classes and Structs
Classes and Structs
Method Argument Passing
Method Argument Passing
The ref modifier causes arguments to be passed by reference
The ref modifier causes arguments to be passed by reference
Allows a method call to modify a variable
Allows a method call to modify a variable
Applies to both value and reference types
Applies to both value and reference types
Have to use ref modifier in method definition
Have to use ref modifier in method definition and
and
in the code that calls it
in the code that calls it
Variable has to have a value before call
Variable has to have a value before call
void OutFunction(out int p) {
p = 22;
} int x;
OutFunction(out x);
// x is now 22
Classes and Structs
Classes and Structs
Method Argument Passing
Method Argument Passing
The
The out
out modifier causes arguments to be passed out by
modifier causes arguments to be passed out by
reference
reference
Allows a method call to initialize a variable
Allows a method call to initialize a variable
Have to use
Have to use out
out modifier in method definition and the
modifier in method definition and the
code that calls it
code that calls it
Argument has to have a value before returning
Argument has to have a value before returning
void Print(int i);
void Print(string s);
void Print(char c);
void Print(float f);
int Print(float f); // Error: duplicate signature
Classes and Structs
Classes and Structs
Overloaded Methods
Overloaded Methods
A type may overload methods, i.e. provide multiple methods with
A type may overload methods, i.e. provide multiple methods with
the same name
the same name
Each must have a unique signature
Each must have a unique signature
Signature is based upon arguments only, the return value is ignored
Signature is based upon arguments only, the return value is ignored
int Sum(params int[] intArr) {
int sum = 0;
foreach (int i in intArr)
sum += i;
return sum;
} int sum = Sum(13,87,34);
Classes and Structs
Classes and Structs
Parameter Arrays
Parameter Arrays
Methods can have a variable number of arguments,
Methods can have a variable number of arguments,
called a parameter array
called a parameter array
params
params keyword declares parameter array
keyword declares parameter array
Must be the last argument
Must be the last argument
class Foo {
public void DoSomething(int i) {
...
}
}
Foo f = new Foo();
f.DoSomething();
Classes and Structs
Classes and Structs
Virtual Methods
Virtual Methods
Methods may be virtual or non-virtual (default)
Methods may be virtual or non-virtual (default)
Non-virtual methods are not polymorphic
Non-virtual methods are not polymorphic
They cannot be overridden
They cannot be overridden
Non-virtual methods cannot be abstract
Non-virtual methods cannot be abstract
Classes and Structs
Classes and Structs
Virtual Methods
Virtual Methods
Defined in a base class
Defined in a base class
Can be overridden in derived classes
Can be overridden in derived classes
Derived classes provide their own specialized implementation
Derived classes provide their own specialized implementation
May contain a default implementation
May contain a default implementation
Use abstract method if no default implementation
Use abstract method if no default implementation
Needed for inheritance-based polymorphism
Needed for inheritance-based polymorphism
Properties, indexers and events can also
Properties, indexers and events can also
be virtual
be virtual
class Shape {
public virtual void Draw() { ... }
}
class Box : Shape {
public override void Draw() { ... }
}
class Sphere : Shape {
public override void Draw() { ... }
}
void HandleShape(Shape s) {
s.Draw();
...
} HandleShape(new Box());
HandleShape(new Sphere());
HandleShape(new Shape());
Classes and Structs
Classes and Structs
Virtual Methods
Virtual Methods
Classes and Structs
Classes and Structs
Abstract Methods
Abstract Methods
An abstract method is virtual and has no implementation
An abstract method is virtual and has no implementation
Must belong to an abstract class
Must belong to an abstract class
Intended to be implemented in a derived class
Intended to be implemented in a derived class
abstract class Shape {
public abstract void Draw();
}
class Box : Shape {
public override void Draw() { ... }
}
class Sphere : Shape {
public override void Draw() { ... }
}
void HandleShape(Shape s) {
s.Draw();
...
}
HandleShape(new Box());
HandleShape(new Sphere());
HandleShape(new Shape()); // Error!
Classes and Structs
Classes and Structs
Abstract Methods
Abstract Methods
Classes and Structs
Classes and Structs
Overloaded vs. Overridden Methods
Overloaded vs. Overridden Methods
Unlike method overriding, method overloading depends upon the type of the
Unlike method overriding, method overloading depends upon the type of the
variable, NOT on the type of the object
variable, NOT on the type of the object
Method overloading is resolved at compile-time
Method overloading is resolved at compile-time
However, at run-time, if the overloaded method is virtual, then the method that
However, at run-time, if the overloaded method is virtual, then the method that
is called is determined by the type of the object
is called is determined by the type of the object
Method overriding is resolved at run-time
Method overriding is resolved at run-time
Classes and Structs
Classes and Structs
Method Versioning
Method Versioning
Must explicitly use
Must explicitly use override
override or
or new
new keywords to
keywords to
specify versioning intent
specify versioning intent
Avoids accidental overriding
Avoids accidental overriding
Methods are non-virtual by default
Methods are non-virtual by default
C++ and Java produce fragile base classes –
C++ and Java produce fragile base classes – cannot
cannot
specify versioning intent
specify versioning intent
Method Versioning in C#
Method Versioning in C#
class Derived : Base // v1.0
class Derived : Base // v1.0
{
{
public virtual void Foo()
public virtual void Foo()
{
{
Console.WriteLine("Derived.Foo");
Console.WriteLine("Derived.Foo");
}
}
}
}
class Base // v1.0
class Base // v1.0
{
{
}
}
class Base
class Base // v2.0
// v2.0
{
{
public virtual void Foo()
public virtual void Foo()
{
{
Database.Log("Base.Foo");
Database.Log("Base.Foo");
}
}
}
}
class Base
class Base // v2.0
// v2.0
{
{
public virtual
public virtual int
int Foo()
Foo()
{
{
Database.Log("Base.Foo"); return 0;
Database.Log("Base.Foo"); return 0;
}
}
}
}
class Derived : Base // v2.0
class Derived : Base // v2.0
{
{
public
public new
new virtual void Foo()
virtual void Foo()
{
{
Console.WriteLine("Derived.Foo");
Console.WriteLine("Derived.Foo");
}
}
}
}
class Derived : Base // v2.0
class Derived : Base // v2.0
{
{
public
public override
override void Foo()
void Foo()
{
{
super.Foo();
super.Foo();
Console.WriteLine("Derived.Foo");
Console.WriteLine("Derived.Foo");
}
}
}
}
Classes and Structs
Classes and Structs
Constructors
Constructors
Instance constructors are special methods that are called when a class or struct is instantiated
Instance constructors are special methods that are called when a class or struct is instantiated
Performs custom initialization
Performs custom initialization
Can be overloaded
Can be overloaded
If a class doesn’t define any constructors, an implicit parameterless constructor is created
If a class doesn’t define any constructors, an implicit parameterless constructor is created
Cannot create a parameterless constructor
Cannot create a parameterless constructor
for a struct
for a struct
All fields initialized to zero/null
All fields initialized to zero/null
Classes and Structs
Classes and Structs
Constructors
Constructors
Order of construction:
Order of construction:
1.
1. Instance variables are initialized
Instance variables are initialized
2.
2. Base constructor is called
Base constructor is called
3.
3. Body of constructor is called
Body of constructor is called
All during construction the object is considered to be the constructed type
All during construction the object is considered to be the constructed type
Avoid calling virtual methods in constructors
Avoid calling virtual methods in constructors
The object may not be property initialized
The object may not be property initialized
This is like Java, but unlike C++
This is like Java, but unlike C++
class B {
private int h;
public B() { }
public B(int h) { this.h = h; }
}
class D : B {
private int i;
public D() : this(24) { }
public D(int i) { this.i = i; }
public D(int h, int i) : base(h) { this.i = i; }
}
Classes and Structs
Classes and Structs
Constructor Initializers
Constructor Initializers
One constructor can call another with a constructor
One constructor can call another with a constructor
initializer
initializer
Can call
Can call this(...)
this(...) or
or base(...)
base(...)
Default constructor initializer is
Default constructor initializer is base()
base()
Classes and Structs
Classes and Structs
Static Constructors
Static Constructors
A static constructor lets you create initialization code that is called once for the class
A static constructor lets you create initialization code that is called once for the class
Guaranteed to be executed before the first instance of a class or struct is created and before any
Guaranteed to be executed before the first instance of a class or struct is created and before any
static member of the class or struct
static member of the class or struct
is accessed
is accessed
No other guarantees on execution order
No other guarantees on execution order
Only one static constructor per type
Only one static constructor per type
Must be parameterless
Must be parameterless
class Foo {
~Foo() {
Console.WriteLine(“Destroyed {0}”, this);
}
}
Classes and Structs
Classes and Structs
Finalizers
Finalizers
A finalizer is a method that is called before an instance is garbage collected
A finalizer is a method that is called before an instance is garbage collected
Different from a C++ destructor
Different from a C++ destructor
Used to clean up any resources held by the instance, do bookkeeping, etc.
Used to clean up any resources held by the instance, do bookkeeping, etc.
Only classes, not structs, can have finalizers
Only classes, not structs, can have finalizers
Classes and Structs
Classes and Structs
Finalizers
Finalizers
Unlike C++, C# finalizers are non-deterministic
Unlike C++, C# finalizers are non-deterministic
They are not guaranteed to be called at a specific time (i.e. they aren’t called when
They are not guaranteed to be called at a specific time (i.e. they aren’t called when
an instance goes out of scope)
an instance goes out of scope)
They are guaranteed to be called before shutdown (...kind of)
They are guaranteed to be called before shutdown (...kind of)
Use the
Use the using
using statement and the
statement and the IDisposable
IDisposable interface to achieve
interface to achieve
deterministic finalization
deterministic finalization
class Car {
string vid;
public static bool operator ==(Car x, Car y) {
return x.vid == y.vid;
}
}
Classes and Structs
Classes and Structs
Operator Overloading
Operator Overloading
User-defined operators
User-defined operators
Must be a static method
Must be a static method
Classes and Structs
Classes and Structs
Operator Overloading
Operator Overloading
+
+ -
- !
! ~
~
true
true false
false ++
++ --
--
Overloadable unary operators
Overloadable unary operators
Overloadable binary operators
Overloadable binary operators
+
+ -
- *
* /
/ !
! ~
~
%
% &
& |
| ^
^ ==
== !=
!=
<<
<< >>
>> <
< >
> <=
<= >=
>=
Classes and Structs
Classes and Structs
Operator Overloading
Operator Overloading
No overloading for member access, method invocation,
No overloading for member access, method invocation,
assignment operators, nor these operators:
assignment operators, nor these operators: sizeof
sizeof,
,
new
new,
, is
is,
, as
as,
, typeof
typeof,
, checked
checked,
, unchecked
unchecked,
, &&
&&,
, ||
||,
,
and
and ?:
?:
The
The &&
&& and
and ||
|| operators are automatically evaluated
operators are automatically evaluated
from
from &
& and
and |
|
Overloading a binary operator (e.g.
Overloading a binary operator (e.g. *
*) implicitly overloads
) implicitly overloads
the corresponding assignment operator (e.g.
the corresponding assignment operator (e.g. *=
*=)
)
Classes and Structs
Classes and Structs
Operator Overloading
Operator Overloading
struct Vector {
int x, y;
public Vector(x, y) { this.x = x; this.y = y; }
public static Vector operator +(Vector a, Vector b) {
return Vector(a.x + b.x, a.y + b.y);
}
...
}
Example
Example
class Note {
int value;
// Convert to hertz – no loss of precision
public static implicit operator double(Note x) {
return ...;
}
// Convert to nearest note
public static explicit operator Note(double x) {
return ...;
}
}
Note n = (Note)442.578;
double d = n;
Classes and Structs
Classes and Structs
Conversion Operators
Conversion Operators
User-defined explicit and implicit conversions
User-defined explicit and implicit conversions
Classes and Structs
Classes and Structs
is
is Operator
Operator
The
The is
is operator is used to dynamically test if the run-
operator is used to dynamically test if the run-
time type of an object is compatible with a given type
time type of an object is compatible with a given type
static void DoSomething(object o) {
if (o is Car)
((Car)o).Drive();
}
Don’t abuse the
Don’t abuse the is
is operator: it is preferable to design an
operator: it is preferable to design an
appropriate type hierarchy with polymorphic methods
appropriate type hierarchy with polymorphic methods
Classes and Structs
Classes and Structs
as
as Operator
Operator
The
The as
as operator tries to convert a variable to a specified
operator tries to convert a variable to a specified
type; if no such conversion is possible the result is
type; if no such conversion is possible the result is null
null
static void DoSomething(object o) {
Car c = o as Car;
if (c != null) c.Drive();
}
More efficient than using
More efficient than using is
is operator: test and convert in
operator: test and convert in
one operation
one operation
Same design warning as with the
Same design warning as with the is
is operator
operator
Classes and Structs
Classes and Structs
typeof
typeof Operator
Operator
The
The typeof
typeof operator returns the
operator returns the System.Type
System.Type object
object
for a specified type
for a specified type
Can then use reflection to dynamically obtain information
Can then use reflection to dynamically obtain information
about the type
about the type
Use
Use GetType()
GetType() to get the type of an instance
to get the type of an instance
Console.WriteLine(typeof(int).FullName);
Console.WriteLine(typeof(System.Int32).Name);
Console.WriteLine(typeof(float).Module);
Console.WriteLine(typeof(double).IsPublic);
Console.WriteLine(typeof(Car).MemberType);
Agenda
Agenda
Review Object-Oriented Concepts
Review Object-Oriented Concepts
Interfaces
Interfaces
Classes and Structs
Classes and Structs
Delegates
Delegates
Events
Events
Delegates
Delegates
Object oriented function pointers
Object oriented function pointers
A reference type encapsulating a method signature and return value
A reference type encapsulating a method signature and return value
Can point to multiple functions
Can point to multiple functions
Thread-safe + and - operations
Thread-safe + and - operations
Foundation for events
Foundation for events
delegate double Func(double x);
delegate double Func(double x);
Func func = new Func(Math.Sin);
Func func = new Func(Math.Sin);
double x = func(1.0);
double x = func(1.0);
public class math {
public class math {
double Sin(double x)
double Sin(double x)
{
{
//return (sin x)
//return (sin x)
}
}
}
}
delegate void Greeting();
delegate void Greeting();
Greeting greeting;
Greeting greeting;
greeting += new Greeting(A.SayHello);
greeting += new Greeting(A.SayHello);
greeting += new Greeting(A.Bow);
greeting += new Greeting(A.Bow);
public class a
public class a
{
{
void SayHello() { //Say Hello }
void SayHello() { //Say Hello }
void Bow() { // bow }
void Bow() { // bow }
}
}
Delegate
Delegate Multicast Delegate
Multicast Delegate
Agenda
Agenda
Review Object-Oriented Concepts
Review Object-Oriented Concepts
Interfaces
Interfaces
Classes and Structs
Classes and Structs
Delegates
Delegates
Events
Events
Events
Events
Specialized multicast delegate
Specialized multicast delegate
Represent a signal that something has occurred in a
Represent a signal that something has occurred in a
program
program
Two main issues
Two main issues
Generating events
Generating events
Consuming events
Consuming events
Events
Events
Overview
Overview
C# has native support for events
C# has native support for events
Based upon delegates
Based upon delegates
An event is essentially a field holding a delegate
An event is essentially a field holding a delegate
However, public users of the class can only register
However, public users of the class can only register
delegates
delegates
They can only call
They can only call +=
+= and
and -=
-=
They
They cannot
cannot invoke the event’s delegate
invoke the event’s delegate
Only the object containing the event can invoke the delegate
Only the object containing the event can invoke the delegate
Multicast delegates allow multiple objects to register with
Multicast delegates allow multiple objects to register with
the same event
the same event
Events
Events
Create a Type defining the information to be passed to
Create a Type defining the information to be passed to
receivers of the event.
receivers of the event.
public class MailManager
public class MailManager
{
{
public class MailMsgEventArgs : EventArgs {
public class MailMsgEventArgs : EventArgs {
public readonly string from, to, body;
public readonly string from, to, body;
public MailMsgEventArgs(string From, string To, string
public MailMsgEventArgs(string From, string To, string
Body) {
Body) {
this.from = From;
this.from = From;
this.to = To;
this.to = To;
this.body = Body;
this.body = Body;
}
}
}
}
}
}
Events
Events
Sourcing
Sourcing
Define the event signature
Define the event signature
Define the event and firing logic
Define the event and firing logic
public delegate void MailMsgEventHandler(object sender,
public delegate void MailMsgEventHandler(object sender,
MailMsgEventArgs e);
MailMsgEventArgs e);
public class MailManager
public class MailManager
{
{
public event MailMsgEventHandler MessageReceived;
public event MailMsgEventHandler MessageReceived;
protected void OnMessageReceived(MailMsgEventArgs e) {
protected void OnMessageReceived(MailMsgEventArgs e) {
if (MessageReceived != null)
if (MessageReceived != null)
MessageReceived(this, e);
MessageReceived(this, e);
}
}
}
}
Events
Events
Create a Method that is responsible for raising the event.
Create a Method that is responsible for raising the event.
public void SimulateArrivingMsg (string from, string to,
public void SimulateArrivingMsg (string from, string to,
string body) {
string body) {
MailMsgEventArgs e = new MailMsgEventArgs(from, to, body);
MailMsgEventArgs e = new MailMsgEventArgs(from, to, body);
OnMailMessageReceived(e);
OnMailMessageReceived(e);
}
}
Events
Events
Handling
Handling
Define and register event handler
Define and register event handler
public class MyForm: Form
public class MyForm: Form
{
{
MailManager FaxApplication;
MailManager FaxApplication;
public MyForm() {
public MyForm() {
FaxApplication = new MailManager();
FaxApplication = new MailManager();
FaxApplication.MessageReceived += new
FaxApplication.MessageReceived += new
MailMsgEventHandler(FaxMsg);
MailMsgEventHandler(FaxMsg);
}
}
void FaxMsg(object sender, MailMsgEventArgs e) {
void FaxMsg(object sender, MailMsgEventArgs e) {
MessageBox.Show("You recd a msg from “ + e.from);
MessageBox.Show("You recd a msg from “ + e.from);
}
}
}
}
Attributes
Attributes
How do you associate information with types and
How do you associate information with types and
members?
members?
Documentation URL for a class
Documentation URL for a class
Transaction context for a method
Transaction context for a method
XML persistence mapping
XML persistence mapping
Traditional solutions
Traditional solutions
Add keywords or pragmas to language
Add keywords or pragmas to language
Use external files, e.g., IDL, DEF
Use external files, e.g., IDL, DEF
C# solution: Attributes
C# solution: Attributes
Attributes
Attributes
Appear in square brackets
Appear in square brackets
Attached to code elements
Attached to code elements
[HelpUrl(“http://SomeUrl/Docs/SomeClass”)]
[HelpUrl(“http://SomeUrl/Docs/SomeClass”)]
class SomeClass
class SomeClass
{
{
[WebMethod]
[WebMethod]
void GetCustomers() { … }
void GetCustomers() { … }
string Test([SomeAttr] string param1) {…}
string Test([SomeAttr] string param1) {…}
}
}
Attribute Fundamentals
Attribute Fundamentals
Can be Intrinsic or Custom
Can be Intrinsic or Custom
Attributes are generic classes!
Attributes are generic classes!
Easy to attach to types and members
Easy to attach to types and members
Attributes can be queried at runtime
Attributes can be queried at runtime
class HelpUrl : System.Attribute {
class HelpUrl : System.Attribute {
public HelpUrl(string url) { … }
public HelpUrl(string url) { … }
…
…
}
}
[HelpUrl(“http://SomeUrl/APIDocs/SomeClass”)]
[HelpUrl(“http://SomeUrl/APIDocs/SomeClass”)]
class SomeClass { … }
class SomeClass { … }
Type type = Type.GetType(“SomeClass”);
Type type = Type.GetType(“SomeClass”);
Attribute[] attributes =
Attribute[] attributes =
type.GetCustomAttributes();
type.GetCustomAttributes();
Creating Attributes
Creating Attributes
Attributes are simply classes
Attributes are simply classes
Derived from System.Attribute
Derived from System.Attribute
Class functionality = attribute functionality
Class functionality = attribute functionality
public class HelpURLAttribute: System.Attribute
public class HelpURLAttribute: System.Attribute
{
{
public HelpURLAttribute(string url) { … }
public HelpURLAttribute(string url) { … }
public string URL { get { … } }
public string URL { get { … } }
public string Tag { get { … } set { … } }
public string Tag { get { … } set { … } }
}
}
Using Attributes
Using Attributes
Just attach it to a class
Just attach it to a class
Use named parameters
Use named parameters
Use multiple attributes
Use multiple attributes
[HelpURL(“
[HelpURL(“http://someurl/”)]
”)]
Class MyClass { … }
Class MyClass { … }
[HelpURL(“
[HelpURL(“http://someurl/”, Tag=“ctor”)]
”, Tag=“ctor”)]
Class MyClass { … }
Class MyClass { … }
[HelpURL(“
[HelpURL(“http://someurl/”),
”),
HelpURL(“http://someurl/”, Tag=“ctor”)]
HelpURL(“http://someurl/”, Tag=“ctor”)]
Class MyClass { … }
Class MyClass { … }
Querying Attributes
Querying Attributes
Use reflection to query attributes
Use reflection to query attributes
Type type = typeof(MyClass);
Type type = typeof(MyClass);
foreach(object attr in type.GetCustomAttributes())
foreach(object attr in type.GetCustomAttributes())
{
{
if(attr is HelpURLAttribute)
if(attr is HelpURLAttribute)
{
{
HelpURLAttribute ha = (HelpURLAttribute) attr;
HelpURLAttribute ha = (HelpURLAttribute) attr;
myBrowser.Navigate(ha.URL);
myBrowser.Navigate(ha.URL);
}
}
}
}

4. OBJECT ORIENTED PROGRAMMING WITH SCOPE AND FEATURES

  • 1.
    Object Oriented Concepts– C# Object Oriented Concepts – C# Q Q
  • 2.
    Agenda Agenda Review Object-Oriented Concepts ReviewObject-Oriented Concepts Interfaces Interfaces Classes and Structs Classes and Structs Delegates Delegates Events Events
  • 3.
    Review Review Key Object-Oriented Concepts KeyObject-Oriented Concepts Inheritance Inheritance The “is a” relationship The “is a” relationship Types are arranged in a hierarchy Types are arranged in a hierarchy Called base/derived or superclass/subclass Called base/derived or superclass/subclass Accord Corvette Car Truck Plane Boat Vehicle Accelerate() Decelerate() TakeOff() Land() OpenTrunk() VIN
  • 4.
    Review Review Key Object-Oriented Concepts KeyObject-Oriented Concepts Polymorphism Polymorphism The ability to perform an operation on an object without knowing The ability to perform an operation on an object without knowing the precise type of the object the precise type of the object Lets “old” code call “new” code Lets “old” code call “new” code void Poly(object o) { Console.WriteLine(o.ToString()); } Poly(42); Poly(“abcd”); Poly(12.345678901234m); Poly(new Point(23,45)); Poly(new PurchaseOrder(“PO11235811”));
  • 5.
    Agenda Agenda Review Object-Oriented Concepts ReviewObject-Oriented Concepts Interfaces Interfaces Classes and Structs Classes and Structs Delegates Delegates Events Events
  • 6.
    Interfaces Interfaces An interface definesa contract An interface defines a contract An interface is a type An interface is a type Can declare variables of that type Can declare variables of that type However, you cannot directly instantiate an interface However, you cannot directly instantiate an interface Includes methods, properties, indexers, events Includes methods, properties, indexers, events Any class or struct implementing an interface must support all parts of Any class or struct implementing an interface must support all parts of the contract the contract Interfaces provide no implementation Interfaces provide no implementation When a class or struct implements an interface it must provide the When a class or struct implements an interface it must provide the implementations for all members of the interface implementations for all members of the interface Interfaces provide polymorphism Interfaces provide polymorphism Many classes and structs may implement a particular interface Many classes and structs may implement a particular interface
  • 7.
    public interface IDisposable{ void Dispose(); } public class TextBox : IDisposable { public void Dispose() { ... } } public class Car : IDisposable { public void Dispose() { ... } } Interfaces Interfaces Example Example void PolyDispose(IDisposable id) { id.Dispose(); } TextBox tb = new TextBox(); PolyDispose(tb); Car c = new Car(); PolyDispose(c);
  • 8.
    Interfaces Interfaces Casting Casting A class thatimplements an interface can be cast A class that implements an interface can be cast (converted) to any of those interfaces (converted) to any of those interfaces public interface IDisposable { } public interface IEnumerable { } public class ListBox : IDisposable, IEnumerable { } ListBox lb = new ListBox(); IDisposable id = (IDisposable)lb; IEnumerable ie = (IEnumerable)lb;
  • 9.
    interface ITextBox { voidSetText(string s); } interface IListBox { void SetItems(string[] items); } interface IComboBox: ITextBox, IListBox { } Interfaces Interfaces Multiple Inheritance Multiple Inheritance Interfaces can inherit from multiple interfaces Interfaces can inherit from multiple interfaces Classes and structs can inherit from Classes and structs can inherit from multiple interfaces multiple interfaces
  • 10.
    Agenda Agenda Review Object-Oriented Concepts ReviewObject-Oriented Concepts Interfaces Interfaces Classes and Structs Classes and Structs Delegates Delegates Events Events
  • 11.
    Classes and Structs Classesand Structs Similarities Similarities Both are user-defined types Both are user-defined types Both can contain Both can contain Data Data Fields, constants, events, arrays Fields, constants, events, arrays Functions Functions Methods, properties, indexers, operators Methods, properties, indexers, operators Constructors, finalizers Constructors, finalizers Type definitions Type definitions Classes, structs, enums, interfaces, delegates Classes, structs, enums, interfaces, delegates Both can implement multiple interfaces Both can implement multiple interfaces Both are instantiated with Both are instantiated with new new operator operator
  • 12.
    Class Class Struct Struct Reference type Referencetype Value type Value type Can inherit from any Can inherit from any non-sealed reference class non-sealed reference class No inheritance No inheritance (inherits only from (inherits only from System.ValueType System.ValueType) ) Can have a finalizer Can have a finalizer No finalizer No finalizer Can have user-defined Can have user-defined parameterless constructor parameterless constructor No user-defined parameterless constructor No user-defined parameterless constructor Classes and Structs Classes and Structs Differences Differences
  • 13.
    C++ Struct C++ StructC# Struct C# Struct Same as C++ class, but all members Same as C++ class, but all members are are public public User-defined value type User-defined value type Can be allocated on the heap, Can be allocated on the heap, on the stack or as a member on the stack or as a member (can be used as value or reference), just (can be used as value or reference), just like C++ class like C++ class Always allocated on the stack or Always allocated on the stack or as a member as a member Members are always Members are always public public Members can be Members can be public public, , internal internal or or private private Classes Classes and Structs and Structs C# Structs vs. C++ Structs C# Structs vs. C++ Structs Very different from C++ struct Very different from C++ struct
  • 14.
    public class Car: Vehicle { public enum Make { GM, Honda, BMW } Make make; string vid; Point location; Car(Make m, string vid; Point loc) { this.make = m; this.vid = vid; this.location = loc; } public void Drive() { Console.WriteLine(“vroom”); } } Car c = new Car(Car.Make.BMW, “JF3559QT98”, new Point(3,7)); c.Drive(); Classes and Structs Classes and Structs Class Class
  • 15.
    public struct Point{ int x, y; public Point(int x, int y) { this.x = x; this.y = y; } public int X { get { return x; } set { x = value; } } public int Y { get { return y; } set { y = value; } } } Point p = new Point(2,5); p.X += 100; int px = p.X; // px = 102 Classes and Structs Classes and Structs Struct Struct
  • 16.
    Classes Classes and Structs andStructs Static vs. Instance Members Static vs. Instance Members By default, members are per instance By default, members are per instance Each instance gets its own fields Each instance gets its own fields Methods apply to a specific instance Methods apply to a specific instance Static members are per type Static members are per type Static methods can’t access instance data Static methods can’t access instance data No No this this variable in static methods variable in static methods Don’t abuse static members Don’t abuse static members They are essentially object-oriented They are essentially object-oriented global data and global functions global data and global functions
  • 17.
    Classes and Structs Classesand Structs Access Modifiers Access Modifiers Access modifiers specify who can use a type Access modifiers specify who can use a type or a member or a member Access modifiers control encapsulation Access modifiers control encapsulation Top-level types (those directly in a namespace) can be Top-level types (those directly in a namespace) can be public public or or internal internal Class members can be Class members can be public public, , private private, , protected protected, , internal internal, or , or protected internal protected internal Struct members can be Struct members can be public public, , private private or or internal internal
  • 18.
    If the access Ifthe access modifier is modifier is Then a member defined in type T and Then a member defined in type T and assembly A is accessible assembly A is accessible public public to everyone to everyone private private within T only (the default) within T only (the default) protected protected to T or types derived from T to T or types derived from T internal internal to types within A to types within A protected internal protected internal to T or types derived from T to T or types derived from T or to types within A or to types within A Classes and Structs Classes and Structs Access Modifiers Access Modifiers
  • 19.
    Classes and Structs Classesand Structs Abstract Classes Abstract Classes An abstract class is one that cannot be instantiated An abstract class is one that cannot be instantiated Intended to be used as a base class Intended to be used as a base class May contain abstract and non-abstract function members May contain abstract and non-abstract function members Similar to an interface Similar to an interface Cannot be sealed Cannot be sealed
  • 20.
    Classes and Structs Classesand Structs Sealed Classes Sealed Classes A sealed class is one that cannot be used as a base class A sealed class is one that cannot be used as a base class Sealed classes can’t be abstract Sealed classes can’t be abstract All structs are implicitly sealed All structs are implicitly sealed System.String is sealed System.String is sealed Why seal a class? Why seal a class? To prevent unintended derivation To prevent unintended derivation Code optimization Code optimization Virtual function calls can be resolved at compile-time Virtual function calls can be resolved at compile-time
  • 21.
    class Person { string name; publicPerson(string name) { this.name = name; } public void Introduce(Person p) { if (p != this) Console.WriteLine(“Hi, I’m “ + name); } } Classes and Structs Classes and Structs this this The The this this keyword is a predefined variable available in keyword is a predefined variable available in non-static function members non-static function members Used to access data and function members unambiguously Used to access data and function members unambiguously
  • 22.
    class Shape { int x,y; public override string ToString() { return "x=" + x + ",y=" + y; } } class Circle : Shape { int r; public override string ToString() { return base.ToString() + ",r=" + r; } } Classes and Structs Classes and Structs base base The The base base keyword is used to access class members that keyword is used to access class members that are hidden by similarly named members of the current are hidden by similarly named members of the current class class
  • 23.
    public class MyClass { publicconst string version = “1.0.0”; public const string s1 = “abc” + “def”; public const int i3 = 1 + 2; public const double PI_I3 = i3 * Math.PI; public const double s = Math.Sin(Math.PI); //ERROR ... } Classes and Structs Classes and Structs Constants Constants A constant is a data member that is evaluated at A constant is a data member that is evaluated at compile-time and is implicitly static (per type) compile-time and is implicitly static (per type) e.g. e.g. Math.PI Math.PI
  • 24.
    Classes and Structs Classesand Structs Fields Fields A field is a member variable A field is a member variable Holds data for a class or struct Holds data for a class or struct Can hold: Can hold: a reference type (e.g. class instance), a reference type (e.g. class instance), a value type (e.g. a struct instance), or a value type (e.g. a struct instance), or an array of class or struct instances an array of class or struct instances (an array is actually a reference) (an array is actually a reference)
  • 25.
    Classes and Structs Classesand Structs Readonly Fields Readonly Fields Similar to a const, but is initialized at Similar to a const, but is initialized at run-time in its declaration or in a constructor run-time in its declaration or in a constructor Once initialized, it cannot be modified Once initialized, it cannot be modified Differs from a constant Differs from a constant Initialized at run-time (vs. compile-time) Initialized at run-time (vs. compile-time) Don’t have to re-compile clients Don’t have to re-compile clients Can be static or per-instance Can be static or per-instance public class MyClass { public static readonly double d1 = Math.Sin(Math.PI); public readonly string s1; public MyClass(string s) { s1 = s; } }
  • 26.
    public class Button:Control { private string _caption; public string caption { get { return _caption; } set { _caption = value; Repaint(); } } } Button b = new Button(); b.caption = "OK"; String s = b.caption; Classes and Structs Classes and Structs Properties Properties A property is a virtual field A property is a virtual field Looks like a field, but is implemented with code Looks like a field, but is implemented with code
  • 27.
    public class Person publicclass Person { { private int age; private int age; public int Age { public int Age { get { return age; } get { return age; } set { age = set { age = value value; ; Console.WriteLine(age); Console.WriteLine(age); } } } } } } Person p = new Person(); Person p = new Person(); p.Age = 27; p.Age = 27; p.Age++; p.Age++; Properties Properties Access to private fields normally requires accessors and Access to private fields normally requires accessors and mutators mutators Properties allow access to private fields as if they were Properties allow access to private fields as if they were public public Person p = new Person(); Person p = new Person(); p.setAge(27); p.setAge(27); p.setAge(p.getAge() + 1); p.setAge(p.getAge() + 1); instead of: instead of: Property Property C# C# Other Other
  • 28.
    Classes and Structs Classesand Structs Properties Properties Properties can be: Properties can be: Read-only (implement only Read-only (implement only get get) ) Not the same as a Not the same as a readonly readonly field field Write-only (implement only Write-only (implement only set set) ) Read/write (implement both Read/write (implement both get get and and set set) )
  • 29.
    Indexers Indexers Index an objectas if it were an array Index an object as if it were an array public class numbers public class numbers { { private int[3] nums; private int[3] nums; public int this[int index] public int this[int index] { { get { return nums[index]; } get { return nums[index]; } set { nums[index] = value; } set { nums[index] = value; } } } } } Numbers Num = new Numbers Numbers Num = new Numbers() (); ; Num[0] = 5; Num[0] = 5; int Val = Num[0]; int Val = Num[0]; Numbers Num = new Numbers Numbers Num = new Numbers() (); ; Num.Set_Nums(0,5); Num.Set_Nums(0,5); int Val = Num.Get_Nums(0); int Val = Num.Get_Nums(0); instead of: instead of: Indexer Indexer C# C# Other Other
  • 30.
    public class ListBox:Control { private string[] _items; public string this[int index] { get { return _items[index]; } set { _items[index] = value; Repaint(); } } } ListBox listBox = new ListBox(); listBox[0] = "hello"; Console.WriteLine(listBox[0]); Classes and Structs Classes and Structs Indexers Indexers An indexer lets an instance behave as a virtual array An indexer lets an instance behave as a virtual array Can be overloaded Can be overloaded (e.g. index by (e.g. index by int int and by and by string string) ) Can be Can be read-only, read-only, write-only, write-only, or read/write or read/write
  • 31.
    Classes and Structs Classesand Structs Methods Methods All code executes in a method All code executes in a method Constructors, finalizers and operators are special types of Constructors, finalizers and operators are special types of methods methods Properties and indexers are implemented with get/set methods Properties and indexers are implemented with get/set methods Methods have argument lists Methods have argument lists Methods contain statements Methods contain statements Methods can return a value Methods can return a value Only if return type is not void Only if return type is not void
  • 32.
    Classes and Structs Classesand Structs Method Argument Passing Method Argument Passing By default, data is passed by value By default, data is passed by value A copy of the data is created and passed to the method A copy of the data is created and passed to the method For value types that are passed by value, variables For value types that are passed by value, variables cannot be modified by a method call cannot be modified by a method call For reference types that are passed by value, the instance For reference types that are passed by value, the instance can be modified by a method call, but the variable itself can be modified by a method call, but the variable itself cannot be modified by a method call cannot be modified by a method call
  • 33.
    void RefFunction(ref intp) { p++; } int x = 10; RefFunction(ref x); // x is now 11 Classes and Structs Classes and Structs Method Argument Passing Method Argument Passing The ref modifier causes arguments to be passed by reference The ref modifier causes arguments to be passed by reference Allows a method call to modify a variable Allows a method call to modify a variable Applies to both value and reference types Applies to both value and reference types Have to use ref modifier in method definition Have to use ref modifier in method definition and and in the code that calls it in the code that calls it Variable has to have a value before call Variable has to have a value before call
  • 34.
    void OutFunction(out intp) { p = 22; } int x; OutFunction(out x); // x is now 22 Classes and Structs Classes and Structs Method Argument Passing Method Argument Passing The The out out modifier causes arguments to be passed out by modifier causes arguments to be passed out by reference reference Allows a method call to initialize a variable Allows a method call to initialize a variable Have to use Have to use out out modifier in method definition and the modifier in method definition and the code that calls it code that calls it Argument has to have a value before returning Argument has to have a value before returning
  • 35.
    void Print(int i); voidPrint(string s); void Print(char c); void Print(float f); int Print(float f); // Error: duplicate signature Classes and Structs Classes and Structs Overloaded Methods Overloaded Methods A type may overload methods, i.e. provide multiple methods with A type may overload methods, i.e. provide multiple methods with the same name the same name Each must have a unique signature Each must have a unique signature Signature is based upon arguments only, the return value is ignored Signature is based upon arguments only, the return value is ignored
  • 36.
    int Sum(params int[]intArr) { int sum = 0; foreach (int i in intArr) sum += i; return sum; } int sum = Sum(13,87,34); Classes and Structs Classes and Structs Parameter Arrays Parameter Arrays Methods can have a variable number of arguments, Methods can have a variable number of arguments, called a parameter array called a parameter array params params keyword declares parameter array keyword declares parameter array Must be the last argument Must be the last argument
  • 37.
    class Foo { publicvoid DoSomething(int i) { ... } } Foo f = new Foo(); f.DoSomething(); Classes and Structs Classes and Structs Virtual Methods Virtual Methods Methods may be virtual or non-virtual (default) Methods may be virtual or non-virtual (default) Non-virtual methods are not polymorphic Non-virtual methods are not polymorphic They cannot be overridden They cannot be overridden Non-virtual methods cannot be abstract Non-virtual methods cannot be abstract
  • 38.
    Classes and Structs Classesand Structs Virtual Methods Virtual Methods Defined in a base class Defined in a base class Can be overridden in derived classes Can be overridden in derived classes Derived classes provide their own specialized implementation Derived classes provide their own specialized implementation May contain a default implementation May contain a default implementation Use abstract method if no default implementation Use abstract method if no default implementation Needed for inheritance-based polymorphism Needed for inheritance-based polymorphism Properties, indexers and events can also Properties, indexers and events can also be virtual be virtual
  • 39.
    class Shape { publicvirtual void Draw() { ... } } class Box : Shape { public override void Draw() { ... } } class Sphere : Shape { public override void Draw() { ... } } void HandleShape(Shape s) { s.Draw(); ... } HandleShape(new Box()); HandleShape(new Sphere()); HandleShape(new Shape()); Classes and Structs Classes and Structs Virtual Methods Virtual Methods
  • 40.
    Classes and Structs Classesand Structs Abstract Methods Abstract Methods An abstract method is virtual and has no implementation An abstract method is virtual and has no implementation Must belong to an abstract class Must belong to an abstract class Intended to be implemented in a derived class Intended to be implemented in a derived class
  • 41.
    abstract class Shape{ public abstract void Draw(); } class Box : Shape { public override void Draw() { ... } } class Sphere : Shape { public override void Draw() { ... } } void HandleShape(Shape s) { s.Draw(); ... } HandleShape(new Box()); HandleShape(new Sphere()); HandleShape(new Shape()); // Error! Classes and Structs Classes and Structs Abstract Methods Abstract Methods
  • 42.
    Classes and Structs Classesand Structs Overloaded vs. Overridden Methods Overloaded vs. Overridden Methods Unlike method overriding, method overloading depends upon the type of the Unlike method overriding, method overloading depends upon the type of the variable, NOT on the type of the object variable, NOT on the type of the object Method overloading is resolved at compile-time Method overloading is resolved at compile-time However, at run-time, if the overloaded method is virtual, then the method that However, at run-time, if the overloaded method is virtual, then the method that is called is determined by the type of the object is called is determined by the type of the object Method overriding is resolved at run-time Method overriding is resolved at run-time
  • 43.
    Classes and Structs Classesand Structs Method Versioning Method Versioning Must explicitly use Must explicitly use override override or or new new keywords to keywords to specify versioning intent specify versioning intent Avoids accidental overriding Avoids accidental overriding Methods are non-virtual by default Methods are non-virtual by default C++ and Java produce fragile base classes – C++ and Java produce fragile base classes – cannot cannot specify versioning intent specify versioning intent
  • 44.
    Method Versioning inC# Method Versioning in C# class Derived : Base // v1.0 class Derived : Base // v1.0 { { public virtual void Foo() public virtual void Foo() { { Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); } } } } class Base // v1.0 class Base // v1.0 { { } } class Base class Base // v2.0 // v2.0 { { public virtual void Foo() public virtual void Foo() { { Database.Log("Base.Foo"); Database.Log("Base.Foo"); } } } } class Base class Base // v2.0 // v2.0 { { public virtual public virtual int int Foo() Foo() { { Database.Log("Base.Foo"); return 0; Database.Log("Base.Foo"); return 0; } } } } class Derived : Base // v2.0 class Derived : Base // v2.0 { { public public new new virtual void Foo() virtual void Foo() { { Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); } } } } class Derived : Base // v2.0 class Derived : Base // v2.0 { { public public override override void Foo() void Foo() { { super.Foo(); super.Foo(); Console.WriteLine("Derived.Foo"); Console.WriteLine("Derived.Foo"); } } } }
  • 45.
    Classes and Structs Classesand Structs Constructors Constructors Instance constructors are special methods that are called when a class or struct is instantiated Instance constructors are special methods that are called when a class or struct is instantiated Performs custom initialization Performs custom initialization Can be overloaded Can be overloaded If a class doesn’t define any constructors, an implicit parameterless constructor is created If a class doesn’t define any constructors, an implicit parameterless constructor is created Cannot create a parameterless constructor Cannot create a parameterless constructor for a struct for a struct All fields initialized to zero/null All fields initialized to zero/null
  • 46.
    Classes and Structs Classesand Structs Constructors Constructors Order of construction: Order of construction: 1. 1. Instance variables are initialized Instance variables are initialized 2. 2. Base constructor is called Base constructor is called 3. 3. Body of constructor is called Body of constructor is called All during construction the object is considered to be the constructed type All during construction the object is considered to be the constructed type Avoid calling virtual methods in constructors Avoid calling virtual methods in constructors The object may not be property initialized The object may not be property initialized This is like Java, but unlike C++ This is like Java, but unlike C++
  • 47.
    class B { privateint h; public B() { } public B(int h) { this.h = h; } } class D : B { private int i; public D() : this(24) { } public D(int i) { this.i = i; } public D(int h, int i) : base(h) { this.i = i; } } Classes and Structs Classes and Structs Constructor Initializers Constructor Initializers One constructor can call another with a constructor One constructor can call another with a constructor initializer initializer Can call Can call this(...) this(...) or or base(...) base(...) Default constructor initializer is Default constructor initializer is base() base()
  • 48.
    Classes and Structs Classesand Structs Static Constructors Static Constructors A static constructor lets you create initialization code that is called once for the class A static constructor lets you create initialization code that is called once for the class Guaranteed to be executed before the first instance of a class or struct is created and before any Guaranteed to be executed before the first instance of a class or struct is created and before any static member of the class or struct static member of the class or struct is accessed is accessed No other guarantees on execution order No other guarantees on execution order Only one static constructor per type Only one static constructor per type Must be parameterless Must be parameterless
  • 49.
    class Foo { ~Foo(){ Console.WriteLine(“Destroyed {0}”, this); } } Classes and Structs Classes and Structs Finalizers Finalizers A finalizer is a method that is called before an instance is garbage collected A finalizer is a method that is called before an instance is garbage collected Different from a C++ destructor Different from a C++ destructor Used to clean up any resources held by the instance, do bookkeeping, etc. Used to clean up any resources held by the instance, do bookkeeping, etc. Only classes, not structs, can have finalizers Only classes, not structs, can have finalizers
  • 50.
    Classes and Structs Classesand Structs Finalizers Finalizers Unlike C++, C# finalizers are non-deterministic Unlike C++, C# finalizers are non-deterministic They are not guaranteed to be called at a specific time (i.e. they aren’t called when They are not guaranteed to be called at a specific time (i.e. they aren’t called when an instance goes out of scope) an instance goes out of scope) They are guaranteed to be called before shutdown (...kind of) They are guaranteed to be called before shutdown (...kind of) Use the Use the using using statement and the statement and the IDisposable IDisposable interface to achieve interface to achieve deterministic finalization deterministic finalization
  • 51.
    class Car { stringvid; public static bool operator ==(Car x, Car y) { return x.vid == y.vid; } } Classes and Structs Classes and Structs Operator Overloading Operator Overloading User-defined operators User-defined operators Must be a static method Must be a static method
  • 52.
    Classes and Structs Classesand Structs Operator Overloading Operator Overloading + + - - ! ! ~ ~ true true false false ++ ++ -- -- Overloadable unary operators Overloadable unary operators Overloadable binary operators Overloadable binary operators + + - - * * / / ! ! ~ ~ % % & & | | ^ ^ == == != != << << >> >> < < > > <= <= >= >=
  • 53.
    Classes and Structs Classesand Structs Operator Overloading Operator Overloading No overloading for member access, method invocation, No overloading for member access, method invocation, assignment operators, nor these operators: assignment operators, nor these operators: sizeof sizeof, , new new, , is is, , as as, , typeof typeof, , checked checked, , unchecked unchecked, , && &&, , || ||, , and and ?: ?: The The && && and and || || operators are automatically evaluated operators are automatically evaluated from from & & and and | | Overloading a binary operator (e.g. Overloading a binary operator (e.g. * *) implicitly overloads ) implicitly overloads the corresponding assignment operator (e.g. the corresponding assignment operator (e.g. *= *=) )
  • 54.
    Classes and Structs Classesand Structs Operator Overloading Operator Overloading struct Vector { int x, y; public Vector(x, y) { this.x = x; this.y = y; } public static Vector operator +(Vector a, Vector b) { return Vector(a.x + b.x, a.y + b.y); } ... } Example Example
  • 55.
    class Note { intvalue; // Convert to hertz – no loss of precision public static implicit operator double(Note x) { return ...; } // Convert to nearest note public static explicit operator Note(double x) { return ...; } } Note n = (Note)442.578; double d = n; Classes and Structs Classes and Structs Conversion Operators Conversion Operators User-defined explicit and implicit conversions User-defined explicit and implicit conversions
  • 56.
    Classes and Structs Classesand Structs is is Operator Operator The The is is operator is used to dynamically test if the run- operator is used to dynamically test if the run- time type of an object is compatible with a given type time type of an object is compatible with a given type static void DoSomething(object o) { if (o is Car) ((Car)o).Drive(); } Don’t abuse the Don’t abuse the is is operator: it is preferable to design an operator: it is preferable to design an appropriate type hierarchy with polymorphic methods appropriate type hierarchy with polymorphic methods
  • 57.
    Classes and Structs Classesand Structs as as Operator Operator The The as as operator tries to convert a variable to a specified operator tries to convert a variable to a specified type; if no such conversion is possible the result is type; if no such conversion is possible the result is null null static void DoSomething(object o) { Car c = o as Car; if (c != null) c.Drive(); } More efficient than using More efficient than using is is operator: test and convert in operator: test and convert in one operation one operation Same design warning as with the Same design warning as with the is is operator operator
  • 58.
    Classes and Structs Classesand Structs typeof typeof Operator Operator The The typeof typeof operator returns the operator returns the System.Type System.Type object object for a specified type for a specified type Can then use reflection to dynamically obtain information Can then use reflection to dynamically obtain information about the type about the type Use Use GetType() GetType() to get the type of an instance to get the type of an instance Console.WriteLine(typeof(int).FullName); Console.WriteLine(typeof(System.Int32).Name); Console.WriteLine(typeof(float).Module); Console.WriteLine(typeof(double).IsPublic); Console.WriteLine(typeof(Car).MemberType);
  • 59.
    Agenda Agenda Review Object-Oriented Concepts ReviewObject-Oriented Concepts Interfaces Interfaces Classes and Structs Classes and Structs Delegates Delegates Events Events
  • 60.
    Delegates Delegates Object oriented functionpointers Object oriented function pointers A reference type encapsulating a method signature and return value A reference type encapsulating a method signature and return value Can point to multiple functions Can point to multiple functions Thread-safe + and - operations Thread-safe + and - operations Foundation for events Foundation for events delegate double Func(double x); delegate double Func(double x); Func func = new Func(Math.Sin); Func func = new Func(Math.Sin); double x = func(1.0); double x = func(1.0); public class math { public class math { double Sin(double x) double Sin(double x) { { //return (sin x) //return (sin x) } } } } delegate void Greeting(); delegate void Greeting(); Greeting greeting; Greeting greeting; greeting += new Greeting(A.SayHello); greeting += new Greeting(A.SayHello); greeting += new Greeting(A.Bow); greeting += new Greeting(A.Bow); public class a public class a { { void SayHello() { //Say Hello } void SayHello() { //Say Hello } void Bow() { // bow } void Bow() { // bow } } } Delegate Delegate Multicast Delegate Multicast Delegate
  • 61.
    Agenda Agenda Review Object-Oriented Concepts ReviewObject-Oriented Concepts Interfaces Interfaces Classes and Structs Classes and Structs Delegates Delegates Events Events
  • 62.
    Events Events Specialized multicast delegate Specializedmulticast delegate Represent a signal that something has occurred in a Represent a signal that something has occurred in a program program Two main issues Two main issues Generating events Generating events Consuming events Consuming events
  • 63.
    Events Events Overview Overview C# has nativesupport for events C# has native support for events Based upon delegates Based upon delegates An event is essentially a field holding a delegate An event is essentially a field holding a delegate However, public users of the class can only register However, public users of the class can only register delegates delegates They can only call They can only call += += and and -= -= They They cannot cannot invoke the event’s delegate invoke the event’s delegate Only the object containing the event can invoke the delegate Only the object containing the event can invoke the delegate Multicast delegates allow multiple objects to register with Multicast delegates allow multiple objects to register with the same event the same event
  • 64.
    Events Events Create a Typedefining the information to be passed to Create a Type defining the information to be passed to receivers of the event. receivers of the event. public class MailManager public class MailManager { { public class MailMsgEventArgs : EventArgs { public class MailMsgEventArgs : EventArgs { public readonly string from, to, body; public readonly string from, to, body; public MailMsgEventArgs(string From, string To, string public MailMsgEventArgs(string From, string To, string Body) { Body) { this.from = From; this.from = From; this.to = To; this.to = To; this.body = Body; this.body = Body; } } } } } }
  • 65.
    Events Events Sourcing Sourcing Define the eventsignature Define the event signature Define the event and firing logic Define the event and firing logic public delegate void MailMsgEventHandler(object sender, public delegate void MailMsgEventHandler(object sender, MailMsgEventArgs e); MailMsgEventArgs e); public class MailManager public class MailManager { { public event MailMsgEventHandler MessageReceived; public event MailMsgEventHandler MessageReceived; protected void OnMessageReceived(MailMsgEventArgs e) { protected void OnMessageReceived(MailMsgEventArgs e) { if (MessageReceived != null) if (MessageReceived != null) MessageReceived(this, e); MessageReceived(this, e); } } } }
  • 66.
    Events Events Create a Methodthat is responsible for raising the event. Create a Method that is responsible for raising the event. public void SimulateArrivingMsg (string from, string to, public void SimulateArrivingMsg (string from, string to, string body) { string body) { MailMsgEventArgs e = new MailMsgEventArgs(from, to, body); MailMsgEventArgs e = new MailMsgEventArgs(from, to, body); OnMailMessageReceived(e); OnMailMessageReceived(e); } }
  • 67.
    Events Events Handling Handling Define and registerevent handler Define and register event handler public class MyForm: Form public class MyForm: Form { { MailManager FaxApplication; MailManager FaxApplication; public MyForm() { public MyForm() { FaxApplication = new MailManager(); FaxApplication = new MailManager(); FaxApplication.MessageReceived += new FaxApplication.MessageReceived += new MailMsgEventHandler(FaxMsg); MailMsgEventHandler(FaxMsg); } } void FaxMsg(object sender, MailMsgEventArgs e) { void FaxMsg(object sender, MailMsgEventArgs e) { MessageBox.Show("You recd a msg from “ + e.from); MessageBox.Show("You recd a msg from “ + e.from); } } } }
  • 68.
    Attributes Attributes How do youassociate information with types and How do you associate information with types and members? members? Documentation URL for a class Documentation URL for a class Transaction context for a method Transaction context for a method XML persistence mapping XML persistence mapping Traditional solutions Traditional solutions Add keywords or pragmas to language Add keywords or pragmas to language Use external files, e.g., IDL, DEF Use external files, e.g., IDL, DEF C# solution: Attributes C# solution: Attributes
  • 69.
    Attributes Attributes Appear in squarebrackets Appear in square brackets Attached to code elements Attached to code elements [HelpUrl(“http://SomeUrl/Docs/SomeClass”)] [HelpUrl(“http://SomeUrl/Docs/SomeClass”)] class SomeClass class SomeClass { { [WebMethod] [WebMethod] void GetCustomers() { … } void GetCustomers() { … } string Test([SomeAttr] string param1) {…} string Test([SomeAttr] string param1) {…} } }
  • 70.
    Attribute Fundamentals Attribute Fundamentals Canbe Intrinsic or Custom Can be Intrinsic or Custom Attributes are generic classes! Attributes are generic classes! Easy to attach to types and members Easy to attach to types and members Attributes can be queried at runtime Attributes can be queried at runtime class HelpUrl : System.Attribute { class HelpUrl : System.Attribute { public HelpUrl(string url) { … } public HelpUrl(string url) { … } … … } } [HelpUrl(“http://SomeUrl/APIDocs/SomeClass”)] [HelpUrl(“http://SomeUrl/APIDocs/SomeClass”)] class SomeClass { … } class SomeClass { … } Type type = Type.GetType(“SomeClass”); Type type = Type.GetType(“SomeClass”); Attribute[] attributes = Attribute[] attributes = type.GetCustomAttributes(); type.GetCustomAttributes();
  • 71.
    Creating Attributes Creating Attributes Attributesare simply classes Attributes are simply classes Derived from System.Attribute Derived from System.Attribute Class functionality = attribute functionality Class functionality = attribute functionality public class HelpURLAttribute: System.Attribute public class HelpURLAttribute: System.Attribute { { public HelpURLAttribute(string url) { … } public HelpURLAttribute(string url) { … } public string URL { get { … } } public string URL { get { … } } public string Tag { get { … } set { … } } public string Tag { get { … } set { … } } } }
  • 72.
    Using Attributes Using Attributes Justattach it to a class Just attach it to a class Use named parameters Use named parameters Use multiple attributes Use multiple attributes [HelpURL(“ [HelpURL(“http://someurl/”)] ”)] Class MyClass { … } Class MyClass { … } [HelpURL(“ [HelpURL(“http://someurl/”, Tag=“ctor”)] ”, Tag=“ctor”)] Class MyClass { … } Class MyClass { … } [HelpURL(“ [HelpURL(“http://someurl/”), ”), HelpURL(“http://someurl/”, Tag=“ctor”)] HelpURL(“http://someurl/”, Tag=“ctor”)] Class MyClass { … } Class MyClass { … }
  • 73.
    Querying Attributes Querying Attributes Usereflection to query attributes Use reflection to query attributes Type type = typeof(MyClass); Type type = typeof(MyClass); foreach(object attr in type.GetCustomAttributes()) foreach(object attr in type.GetCustomAttributes()) { { if(attr is HelpURLAttribute) if(attr is HelpURLAttribute) { { HelpURLAttribute ha = (HelpURLAttribute) attr; HelpURLAttribute ha = (HelpURLAttribute) attr; myBrowser.Navigate(ha.URL); myBrowser.Navigate(ha.URL); } } } }

Editor's Notes

  • #3 The term object sometimes refers to an instance and sometimes to a class. It’s meaning can usually be determined by context.
  • #4 An interface is a well-defined set of methods (functions). Interfaces do not contain data members. Type is different from class. The type specifies the interfaces, the class specifies the implementation.
  • #7 Polymorphism is achieved through: Inheritance: a base type can have multiple derived types Interfaces: multiple types can implement a given interface Late binding: you can use any object, as long as it implements the methods you want to call. In C# you can use reflection to dynamically determine if an object implements a method, and then call it. Interfaces can also be used in a late-bound manner. In order to handle multiple types without polymorphism you have to write conditional code (using if or switch statements) that tests the type of an instance and then runs the appropriate code. Such code is not easily extended. Object-Oriented design concepts are motivated for minimizing dependencies. You want to be able to develop independent modules, so that making a change to one doesn’t force you to have to go back and change others.
  • #14 In scenarios where completely different objects need to support some kind of shared functionality like, let’s say, persist to XML, classes can implement interfaces that make them compatible with even if they don’t share the same base class. This provides most of the benefits of multiple class inheritance without the nasty side-effects that this usually brings. Interface members are implicitly public and abstract.
  • #19 Classes and structs provide a way to create user-defined types.
  • #21 The C++ and C# structs are alike in name only.
  • #26 protected internal = protected OR internal. No way to define protected AND internal.
  • #33 Constants are compiled into client programs, while readonly fields are not.
  • #35 Properties are what we refer to as ‘smart fields’, where a field is just another name for an instance variable of a class. Now normally, to allow a user outside of a class to access a private instance variable, the creator of the class would write a public method to get the value of the instance variable, also known as an accessor, and a public method to set the value of the instance variable, also known as mutator. The side effect of constructing a class in this manner is that the way an instance variable is accessed from within the class is different from the way it accessed from outside of the class. Properties allow a user to access a private instance variable as if they were declared public without having to use accessors and mutators. To a user outside of the class, accessing a property looks no different then if that user was to access a instance variable that was declared public. Internally, a property has a get method and a set method which allow the creator of the class to control how an instance variable is accessed and modified. The syntax required to use a property is much simpler than using get/set methods. Properties make it easier for a professor to write code libraries for his or her class that beginning students can understand more quickly.
  • #37 An indexer is a member of an object that allows that object to be treated as an array. Indexers provide you with a simple and intuitive way of accessing elements of a collection that is contained within a class or a struct via an array’s [] syntax. Indexers are flexible in that they support any type, such as integers or strings, as indexes. A good example of where indexers are an advantage is the case where you need an array that has the ability to perform functions beyond those that are already included in the Array class, like Sort and Length . For instance, you might want an array of integers that can return the average of the values it contains. Indexers can be used to create such an array. Indexers can be overloaded
  • #41 Having to declare ref in the caller helps make the code more readable and maintainable.
  • #44 In the example, the Add function can be called with a variable number of arguments. Here, there are 3 arguments. Each is put into the intArr array. The function then iterates over the array, producing the sum of the 3 numbers.
  • #45 When you call a non-virtual method M (DoSomething) on a class C (Foo), you are guaranteed that C.M (Foo.DoSomething) will be called.
  • #52 Let’s say that we have a base class that doesn’t do anything interesting. BUILD: Then a user of this class inherited this class and create a method named Foo() BUILD: Then the creator of the original base class realizes how Foo-ness is important and decided to implement that in the base class. Then we have a problem. How should this behave? Should the clients keep calling Derived.Foo or Base.Foo. In C# it is guaranteed that Derived.Foo will be the one being called because it will most likely preserve the behaviour expected by the client. However the compiler will issue an warning saying that method Base.Foo was hidden. BUILD: To suppress the warning, the programmer can use the keyword new, and explicitly hide the method Base.Foo. BUILD: Or if he can just override as any virtual method.
  • #53 Let’s say that we have a base class that doesn’t do anything interesting. BUILD: Then a user of this class inherited this class and create a method named Foo() BUILD: Then the creator of the original base class realizes how Foo-ness is important and decided to implement that in the base class. Then we have a problem. How should this behave? Should the clients keep calling Derived.Foo or Base.Foo. In C# it is guaranteed that Derived.Foo will be the one being called because it will most likely preserve the behaviour expected by the client. However the compiler will issue an warning saying that method Base.Foo was hidden. BUILD: To suppress the warning, the programmer can use the keyword new, and explicitly hide the method Base.Foo. BUILD: Or if he can just override as any virtual method.
  • #54 Let’s say that we have a base class that doesn’t do anything interesting. BUILD: Then a user of this class inherited this class and create a method named Foo() BUILD: Then the creator of the original base class realizes how Foo-ness is important and decided to implement that in the base class. Then we have a problem. How should this behave? Should the clients keep calling Derived.Foo or Base.Foo. In C# it is guaranteed that Derived.Foo will be the one being called because it will most likely preserve the behaviour expected by the client. However the compiler will issue an warning saying that method Base.Foo was hidden. BUILD: To suppress the warning, the programmer can use the keyword new, and explicitly hide the method Base.Foo. BUILD: Or if he can just override as any virtual method.
  • #56 Let’s say that we have a base class that doesn’t do anything interesting. BUILD: Then a user of this class inherited this class and create a method named Foo() BUILD: Then the creator of the original base class realizes how Foo-ness is important and decided to implement that in the base class. Then we have a problem. How should this behave? Should the clients keep calling Derived.Foo or Base.Foo. In C# it is guaranteed that Derived.Foo will be the one being called because it will most likely preserve the behaviour expected by the client. However the compiler will issue an warning saying that method Base.Foo was hidden. BUILD: To suppress the warning, the programmer can use the keyword new, and explicitly hide the method Base.Foo. BUILD: Or if he can just override as any virtual method.
  • #57 Let’s say that we have a base class that doesn’t do anything interesting. BUILD: Then a user of this class inherited this class and create a method named Foo() BUILD: Then the creator of the original base class realizes how Foo-ness is important and decided to implement that in the base class. Then we have a problem. How should this behave? Should the clients keep calling Derived.Foo or Base.Foo. In C# it is guaranteed that Derived.Foo will be the one being called because it will most likely preserve the behaviour expected by the client. However the compiler will issue an warning saying that method Base.Foo was hidden. BUILD: To suppress the warning, the programmer can use the keyword new, and explicitly hide the method Base.Foo. BUILD: Or if he can just override as any virtual method.
  • #58 In C#, when you create a new base class and you drop that library into your code in binary form, you end up having two Foo methods. The derived class hides the base class’ Foo method, which is fine because the derived class was written at a time when the base class didn’t have a Foo, so there’s clearly no dependency on Foo. You can still access Now, let’s say you have access to the source code of the Base class and if you recompile the Derived class against the new Base class, the compiler will report a warning. The warning says you are hiding an inherited method. Your code will still compile, but you can shut up the warning by putting a “new” directive on the base class’ Foo method. In essence, you will say this is a new public virtual Foo and that you mean to hide the Base class method. You can also determine that you like the new Foo method that the v2 Base class library has produced. And you can create a new version of your Derived class’ Foo method that requires v2 of the Base class’ Foo method. You can express that using the override declaration. The key here is that unless you say the word override, it isn’t an override. And that’s the only way to make this problem go away. Basically, you give the programmer a way to express his intent. There are other aspects to versioning that pertain to constructors, operator overloading, etc, but we won’t dive into those here.
  • #59 If a class defines any constructors, then the implicit parameterless constructor is not created.
  • #60 If a class defines any constructors, then the implicit parameterless constructor is not created.
  • #61 B.B() is needed because once B.B(int h) was defined, the default parameterless constructor is no longer created. Can’t call both : base() and : this() because it would then be ambiguous as to how the base class is constructed.
  • #74 A delegate is what we like to refer to as an object-oriented function pointer. From a C programming perspective, a Delegate is a function pointer – most usually used as a callback in Windows Technically it is a reference type encapsulating a method signature and return value. Attributes of a delegate It represents a class It is type safe Can combine multiple delegates in a single delegate Work for both static and instance methods Inside or outside classes Here are some examples of declarations of delegates. In the blue box we see a math function called Func that takes a double and returns a double. Above the function we have created a delegate that takes a double and returns a double as well. In order to create the delegate, you simply invoke the new operator and pass it the Math.Sin function. The Math.Sin function, of course, has the same method signature as the Func delegate, it takes a double and returns a double. By creating this new Func delegate and invoking it, you are really invoking the Sin object in the Math library. A function pointer is a object that points to a function’s address in memory, or its entry point, and through the function pointer, you can invoke that function. A function pointer always points to a function with a specific signature, thus, all functions you want to use with the same function pointer must have the same parameters and return-type. The problem that arises is that in C++, a function and a static method of an object have a different signature than a non-static method of an object. Unlike a function pointer, the same delegate can be used to point to both a static and a non-static method of an object. A delegate is a combination of a reference to an object and a method on that object. The delegate encapsulates both a method and the object instance that the method is associated with. When invoking a delegate, you are invoking that method on that object. Also unlike a function pointer, a single delegate can point to multiple functions at the same time. This is a special type of delegate called a multicast delegate. The difference between a delegate and a multicast delegate is that a multicast delegate must return void. Multicast delegates have an invocation list, which is the list of functions that are invoked when the delegate is called. C# uses the add and subtract operators to add and remove functions from a multicast delegate’s invocation list. Multicast delegates are the foundation for events in the entire .NET framework. Events will be discussed shortly.
  • #75 Delegates are essentially function pointers. This is the mechanism used to implement event in the frameworks. In the example we first declare a delegate for a function that returns double and receives a double as a parameter. We then instantiate the delegate, telling it to use Math.Sin as the function. Finally we invoke the delegate we created. The power is in the fact that once instantiated, a delegate can be passed around and then invoked at some later time.
  • #82 An event can be thought of as a property for a multicast delegate. Just as a property allows a programmer to control access to a private instance variable, an event controls access to a multicast delegate. An event insures that only the += and -= operators can be performed on a delegate from outside of the class in which it was declared. Only the class that declared the event has the ability to invoke it or clear its invocation list. An event is used to allow one object to notify other objects that something has occurred, such as a key press or a mouse click. When dealing with events there are two main issues: - One, how do you become the source of an event, or, how do you become an object that generates an event ? - Two, how do you consume an event that was generated by another object ?
  • #85 So, lets look at how you become the source of an event. First, I declare a multicast delegate with the same signature as the event I want to create. We see such a delegate in the top blue box. Note that the return type of the delegate is void so it is a multicast delegate. To build the actual event, I create an instance of SomeDelegate just as I did before, but now include the event keyword. This can be seen in the second blue box. I have created an event of type SomeDelegate named click. In order to fire the event, all I need to do is invoke it as we see on the last line. There are no special language constructs for firing an event. Internally, when an event is fired, the delegate represented by the event is invoked. Here, I first check if any object is listening to the event, then if true, call the click event. Because the event is multicast, it could possibly have multiple listeners.
  • #87 To handle an event, you define an event handler then register it with the event. What I do is first create an instance of a “Button” object called okButton. I then register the okButtonClick method , which here serves as an event handler, with the okButton.click event. Notice how I’m using the += operator to add the event handler. Before I give show you a real life demonstration of event handling in a Window Form application, I would like to emphasize a few more attributes of the way delegates are implemented. It’s worth pointing out that delegates perform very well (fast) – Because your application can determine if an event is subscribed to before sending an event. They are typesafe Provide multicasting support.
  • #88  So, one of the key features in C# is a thing called attributes. It’s something that exists in very few other languages. Attributes are basically about answering the question on the slide: How do I associate information with members and types? How do I specify the documentation URL for a class, what is the transaction context for a method, how does the class persist to XML, or whatever you want to dream up. ** Attributes provide for a way to add meta-data to a class, method, … which turns out to be a very powerful tool in C# and in the CLR in general. We already support the notion of putting information such as private, public, etc on a class or member. Attributes are ways of adding additional data, such as “not only is this class public, but here is the documentation for it”, or “here is the way it persists as XML”, or whatever you can think of. Traditional solutions see language designers adding new keywords or pragmas to the language. Other solutions include the use of external files such as IDL files or DEF files. Neither of those solutions are extensible. C# takes a different view of it.
  • #89 I think the best way to understand attributes is to see it in use. Here is a real world example. Let’s say you have some class. That class has some documentation associated with it. So, we create an attribute called HelpURL, and I’ll show you in a second how to create that attribute. So, we decorate this class declaration with the bracket designation and the Attribute class name inside. The attribute we’re going to create allows a class to reference an external URL for additional documentation, so naturally we’ll need to specify the URL here. Also take note of the WebMethod attribute, we’ll discuss that in a second.
  • #90 Intrinsic ones are provided as part of the CRL, programmer create the Custom ones. Creating an Attribute involves extending the System.Attribute class. Within the attribute class you can have methods, properties, etc. You then attach the attribute to the class as we did in the previous class. Now, when we compile the class the attributes get pickled away with the class. They can then be queried at runtime in a typesafe fashion using a simple reflection procedure. It’s a truly extensible mechanism for hanging additional declarative information onto types and members and then examining them at runtime.
  • #91 It’s simply a class and a way to think about it is that the class functionality is the attribute functionality. We’ll talk about what that means in a second. I have a class declaration here with a constructor. I have two properties, one for the URL and one for the Tag. But, essentially it’s just a class.
  • #92 Well, now I can attach it to a class. Now, look at how I’m using the name HelpURL instead of HelpURLAttribute. Essentially, there’s a naming pattern here going on that says that whenever the compiler sees the word Attribute it can shorten it to not use the Attribute text. Well, in this second example you can see another thing that says “Tag = ctor”. Attributes can have both required parameters and named parameters. Required parameters are those parameters that are necessary for the attribute to function. A named parameter is any public property that is read/write. In our original declaration, Tag is a read/write property. We recognized that people are going to have attributes that will have many optional properties. We didn’t want to force people to create huge constructors. So, we allow you to simply use the properties without implementing massive quantities of constructors. The third example shows how you can attach multiple attributes to a class.
  • #93 Now that you’ve created an attribute, how do you walk up to it in the middle of your program and query the class its attached to for the information contained inside the attribute? Well, you use reflection to query the class and find out what kind of attributes its support. I can use the type operator in C#, pass in the class, and returns the type object for the class. I then invoke a method on that type called GetCustomAttributes. This is the only time where those attributes are created. They do not get created when they are instantiated. They are created only when you need them to be created, in this case when I invoke the GetCustomAttributes method. Once I get the attribute, I can cast it to its attribute class type and then party on that attribute, retrieving information about the class.