csharp in detail part2
TRANSCRIPT
© { JSL }11
C#
in D
etai
lC
# in
Det
ail Jon Jagger
Software Trainer, Designer, Consultant
www.jaggersoft.com
jon@ jaggersoft.com
{ JSL }
Part 2Part 2
© { JSL }22
Bla
tan
t A
dve
rtB
lata
nt
Ad
vert
an interactive, friendly, expert instructoran interactive, friendly, expert instructor Jon has worked for Microsoft using C#Jon has worked for Microsoft using C#
lots of great exerciseslots of great exercises to make sure you understandto make sure you understand
even more slideseven more slides with detail, explanations, and rationaleswith detail, explanations, and rationales
full slide notesfull slide notes include careful comparisons with C++ and include careful comparisons with C++ and
JavaJava
C# in DetailC# in Detailis also available as anis also available as an
instructor led courseinstructor led course
© { JSL }33
Ag
end
aA
gen
da
stringstring classclass constructorsconstructors fieldsfields parametersparameters arraysarrays boxingboxing exceptionsexceptions garbage collectiongarbage collection inheritance, interfaces, abstract classesinheritance, interfaces, abstract classes nested typesnested types delegates and eventsdelegates and events namespacesnamespaces assembliesassemblies attributesattributes reflectionreflection
© { JSL }44
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
stri
ng
stri
ng
© { JSL }55
stri
ng
Typ
est
rin
g T
ype
stringstring is a reference type is a reference type the only one with a literal syntaxthe only one with a literal syntax immutable; just like in Javaimmutable; just like in Java
s
stack heap
null
@t
static void Main(){ string s = null; string t = "Hiker"; ... t[0] = 'B';} Hiker
compile time error
© { JSL }66
ind
exer
ind
exer
stringstring has a readonly indexer has a readonly indexer integer index is always bounds checkedinteger index is always bounds checked throws ArgumentOutOfRangeExceptionthrows ArgumentOutOfRangeException
static void Func(string s){ for (int i = 0; i != s.Length; i++) { char c = s[i]; Console.Write(c); }}
© { JSL }77
Sys
tem
.Str
ing
Sys
tem
.Str
ing
stringstring is an alias for System.String is an alias for System.String
namespace System{ public sealed class String ... { ... // static methods public static int Compare(string, string); public static bool Equals(string, string); public static string Format(string, params object[]); ... // readonly property public int Length { get; } // readonly indexer public char this [int index] { get; } // instance methods public int CompareTo(string); public override bool Equals(object); public new bool Equals(string); ... }}
© { JSL }88
Str
ing
Bu
ilder
Str
ing
Bu
ilder
System.Text.StringBuilder System.Text.StringBuilder
namespace System.Text{ public sealed class StringBuilder { public StringBuilder(); // read-write properties public int Length { get; set; } public int Capacity { get; set; } // read-write indexer public char this [int index] { get; set; } // instance methods public StringBuilder Append(...); public StringBuilder Insert(...); public StringBuilder Remove(int, int); public StringBuilder Replace(...); ... public override string ToString(); }}
© { JSL }99
stri
ng
Lit
eral
sst
rin
g L
iter
als
usual syntaxusual syntax embedded escape chars, but no octalembedded escape chars, but no octal
unusual syntaxunusual syntax @ verbatim string literals@ verbatim string literals
"c:\temp"
@"c:\temp"
@"quote"" char"
@"MP: we got a slugJC: does it talk?MP: yupJC: I'll have it"
c: emp
c:\temp
quote"char
MP: we got a slugJC: does it talk?MP: yupJC: I'll have it
© { JSL }1010
stri
ng
Op
erat
ors
stri
ng
Op
erat
ors
equality operators are overloadedequality operators are overloaded they compare the values not the referencesthey compare the values not the references relational operators are not overloadedrelational operators are not overloaded
binary + is overloaded, forwards to .Concatbinary + is overloaded, forwards to .Concat operator += toooperator += too
IsTrue(s == t);IsTrue(s.Equals(t));IsFalse((object)s == (object)t);
s
stack heap
@
@t Hiker
Hiker
IsTrue(s == t);IsTrue(s.Equals(t));IsTrue((object)s == (object)t);
s @
@t
Hiker
© { JSL }1111
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
clas
scl
ass
© { JSL }1212
clas
s D
ecla
rati
on
clas
s D
ecla
rati
on
a user-defined a user-defined referencereference type type
class Pair{ public int X, Y;};
optional semi-colon
by convention publicnames start with anuppercase letter(PascalCasing)
class Pair{ private int x, y;}
...and private names start with alowercase letter(camelCasing)
class Pair{ int x, y;}
default accessis private
© { JSL }1313
ob
ject
Cre
atio
no
bje
ct C
reat
ion
a a classclass local variable lives on the stack local variable lives on the stack is not definitely assignedis not definitely assigned can be initialised with can be initialised with nullnull or a c'tor call or a c'tor call
p
stack
?
.X
.Y
heap
required
static void Main(){ Pair p;}
static void Main(){ Pair p = null;}
static void Main(){ Pair p = new Pair();}
p null
p @ 0
0
© { JSL }1414
clas
s C
on
stru
cto
rcl
ass
Co
nst
ruct
or
usual usual classclass rules rules compiler declares a default c'torcompiler declares a default c'tor you can declare the default c'toryou can declare the default c'tor if you declare a c'tor the compiler doesn'tif you declare a c'tor the compiler doesn't
class Pair{}
you declare a default c'tor
class Pair{ public Pair(int x, int y) {...} }
compiler declares a default c'tor
class Pair{ public Pair() { ... }}
no one declares a default c'tor
© { JSL }1515
: th
is(.
..):
this
(...)
a c'tor can call a sibling c'tora c'tor can call a sibling c'tor syntax is a cross between C++ and Javasyntax is a cross between C++ and Java no general member-init-list syntax thoughno general member-init-list syntax though
class Point{ public Point(int x, int y) : this(x, y, Colour.Red) { } public Point(int x, int y, Colour c) { ... } ... private int x, y; private Colour c;}
© { JSL }1616
inst
ance
Fie
lds
inst
ance
Fie
lds
instance fields...instance fields... are default initialised by default in all c'torsare default initialised by default in all c'tors can be initialised in variable initialisercan be initialised in variable initialiser can be explicitly initialised in a c'torcan be explicitly initialised in a c'tor
class Point{ public Point(int x, int y) { this.x = x; y = y; } ... private int x; private int y = 42;}
no warning!
OKOK
OK
© { JSL }1717
read
on
ly F
ield
sre
ado
nly
Fie
lds
readonlyreadonly instance fields... instance fields... are instance fields that cannot be assigned toare instance fields that cannot be assigned to
compile time errors
class Pair{ public Pair(int x, int y) { this.x = x; this.y = y; } public void Reset() { x = 0; y = 0; } private readonly int x, y;}
this declares Pair as an immutable object
© { JSL }1818
con
st F
ield
sco
nst
Fie
lds
constconst fields are implicitly fields are implicitly staticstatic only simple types, only simple types, enumenums, & s, & stringstring can be can be constconst constconst fields require a variable initializer fields require a variable initializer
class Pair{ private const int x = 0, y = 0;}
class BadFields{... BadFields(...) { question = 9 * 6; }... static const int answer = 42;... const int question;... const Pair origin = new Pair();}
OK
compiletimeerrors
this declares Pair with no instance fields
© { JSL }1919
stat
ic F
ield
sst
atic
Fie
lds
to declare to declare staticstatic fields of other types fields of other types useuse static static keyword keyword!! staticstatic fields are default initialised fields are default initialised staticstatic fields can use variable initialisers fields can use variable initialisers access is via typename onlyaccess is via typename only
class Pair{... static Pair origin;... static Pair topLeft = new Pair(10,20);... static AnyClass field;... static string both = "Arthur";}
Pair p = new Pair();...F(p.Origin); // compile-time errorF(Pair.Origin); // OK
© { JSL }2020
stat
ic C
on
stru
cto
rst
atic
Co
nst
ruct
or
a a staticstatic c'tor initialises the type c'tor initialises the type can initialize can initialize staticstatic fields but not fields but not constconst fields fields called by VES when the type is loadedcalled by VES when the type is loaded cannot be called, no access modifier allowedcannot be called, no access modifier allowed
class GoodExample{ static GoodExample() { origin = new Pair(0,0); }...static readonly Pair origin;}
OK
class BadExample{ public static GoodExample() { x = 42; }...const int x;}
compile time errors
© { JSL }2121
Co
py
Par
amet
ers
Co
py
Par
amet
ers
a plain parameter is a a plain parameter is a copycopy of the argument of the argument no frills bitwise copyno frills bitwise copy the argument must be definitely assignedthe argument must be definitely assigned argument can be an "rvalue"argument can be an "rvalue"
static void Method(Pair parameter){ parameter = new Pair(42,42);}
static void Main(){ Pair arg = new Pair(0,0); Console.WriteLine(arg.X); Method(arg); Console.WriteLine(arg.X);}
00
© { JSL }2222
ref
Par
amet
ers
ref
Par
amet
ers
a a refref parameter is an parameter is an aliasalias for the argument for the argument no copy takes placeno copy takes place argument must be definitely assignedargument must be definitely assigned argument must be an "lvalue"argument must be an "lvalue" refref required on argument required on argument andand parameter parameter
static void Method(ref Pair parameter){ parameter = new Pair(42,42);}
static void Main(){ Pair arg = null; //Console.WriteLine(p.X); Method(ref arg); Console.WriteLine(arg.X);}
42
Method( ref type [ ] array ) allowed
© { JSL }2323
ou
t P
aram
eter
so
ut
Par
amet
ers
an an outout parameter is an parameter is an aliasalias for the argument for the argument no copy takes placesno copy takes places argument need not be definitely assignedargument need not be definitely assigned parameter must be definitely assignedparameter must be definitely assigned argument must be an "lvalue"argument must be an "lvalue" outout required on argument required on argument andand parameter parameter
static void Method(out Pair parameter){ parameter = new Pair(42,42);}
static void Main(){ Pair arg; //Console.WriteLine(p.X); Method(out arg); Console.WriteLine(arg.X);}
42
Method( out type [ ] array ) allowed
© { JSL }2424
in P
aram
eter
s?in
Par
amet
ers?
readonlyreadonly, , const,const, and and inin, are all C# keywords, are all C# keywords they cannot be applied to parametersthey cannot be applied to parameters reference types reference types alwaysalways grant write access grant write access
argument parameter
optional
required
Copy
ref
out
@
@
@
@
@@
@@
0 0initialize
© { JSL }2525
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
[ ]
Arr
ays
[ ]
Arr
ays
© { JSL }2626
Arr
ay V
aria
ble
sA
rray
Var
iab
les
C# supports rectangular arraysC# supports rectangular arrays rectangular arrays are reference typesrectangular arrays are reference types
int[] row = null;
int[,] grid = null;
int[,,] threeD = null;
row
stack heap
null
nullgrid
© { JSL }2727
Arr
ay In
stan
ces
Arr
ay In
stan
ces
array instances are created using array instances are created using newnew rectangular arrays must specify rectangular arrays must specify allall dimensions dimensions array instance elements are default initialisedarray instance elements are default initialised
int[] row = new int[4];
int[,] grid = new int[2,3];
row
stack heap
@
@grid
0 0 0 0
0 0 0 0 0 0
array of structs
© { JSL }2828
Arr
ay In
itia
lisat
ion
Arr
ay In
itia
lisat
ion
arrays can be initialisedarrays can be initialised omitted initialisers are not permittedomitted initialisers are not permitted array size may be omittedarray size may be omitted standard shortcut notationstandard shortcut notation
int[] row = new int[4] {1,2,3,4};
int[,] grid = new int[,] { {1,2,3}, {4,5,6,}, };
int[,] shortcut = { {1,2,3}, {4,5,6} };
row
stack heap
@
@grid
1 2 3 4
1 2 3 4 5 6
trailingcommasarepermitted
© { JSL }2929
Sys
tem
.Arr
ayS
yste
m.A
rray
all array types inherit from System.Arrayall array types inherit from System.Array
namespace System{ public class Array { protected Array(); ... // readonly properties public int Length { get; } public int Rank { get; } // instance methods public int GetLength(int); // static methods public static void Clear(Array, int, int); ... }}
int[,] cosmic = { {1,2,3}, {4,5,6} };Console.Write(cosmic.Length);Console.Write(cosmic.Rank);Console.Write(cosmic.GetLength(0));Console.Write(cosmic.GetLength(1));
6223
© { JSL }3030
Usi
ng
Arr
ays
Usi
ng
Arr
ays
all array access is bounds checkedall array access is bounds checked throws IndexOutOfRangeExceptionthrows IndexOutOfRangeException
class Example{ static void Use(int[,] grid) { int rowLength = grid.GetLength(0); int colLength = grid.GetLength(1); for (int row = 0; row != rowLength; row++) { for (int col = 0; col != colLength; col++) { Console.WriteLine(grid[row,col]); } } } static void Main() { Use(new int[,]{ {1,2,3}, {4,5,6} }); ... }}
there is no direct way to make rowLength constant
© { JSL }3131
Rag
ged
Arr
ays
Rag
ged
Arr
ays
C# also supports ragged arrays C# also supports ragged arrays arrays of arraysarrays of arrays array instance still created using array instance still created using newnew
int[][] ragged = new int[3][ ];
int[][][] tatters = null;
ragged
stack heap
@ null null null
tatters null
© { JSL }3232
Rag
ged
Init
ialis
atio
nR
agg
ed In
itia
lisat
ion
each sub array can be intialised as beforeeach sub array can be intialised as before you can only specify the first dimensionyou can only specify the first dimension
int[][] ragged = new int[3][4];
int[][] ragged = new int[3][] { new int[2], null, new int[4]{ 1, 2, 3, 4 } };
ragged
stack heap
@ @ null @
0 0 1 2 3 4
{ ... } shorthandallowed herebut not here
compile time error
© { JSL }3333
par
ams
typ
e[ ]
par
ams
typ
e[ ]
C# supports variadic functionsC# supports variadic functions paramsparams keyword can be used on array parameter keyword can be used on array parameter only on a single dimension array parameteronly on a single dimension array parameter
static void GreyHole(params int[] row){ if (row != null) Console.WriteLine(row.Length); else Console.WriteLine("null");}
static void Main(){ GreyHole(null); GreyHole(); GreyHole(1); GreyHole(new int[]{1, 2}); GreyHole(1,2,3);}
null0123
params is not part of the signature
© { JSL }3434
par
ams
ob
ject
[ ]
par
ams
ob
ject
[ ]
paramsparams with with objectobject as the element type as the element type creates a truly variadic functioncreates a truly variadic function thanks to boxingthanks to boxing
static void BlackHole(params object[] row){ if (row != null) Console.WriteLine(row.Length); else Console.WriteLine("null");}
static void Main(){ BlackHole(null); BlackHole(); BlackHole(1M); BlackHole(new int[]{1,2}); BlackHole(1, 2.0, "three");}
null0113
© { JSL }3535
Arr
ay N
ote
sA
rray
No
tes
int[ ] illegal[ , ];
class Base {...}class Derived : Base {...}
Derived[] ds = new Derived[]{...};Base[] bs = ds;
unsafe { int * array = stackalloc int[42]; ...}
only one syntax
C# supportsarray covariance
you can createan array on thestack, but only in unsafe code
object o = new int[42]; arrays are reference types
int[ ][ , ] mixed; you can mix the two kinds of arrays
© { JSL }3636
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Bo
xin
gB
oxi
ng
© { JSL }3737
Rec
apR
ecap value typesvalue types
variables contain their own data directlyvariables contain their own data directly local variables always live on the stacklocal variables always live on the stack
reference typesreference types variables refer to their data indirectlyvariables refer to their data indirectly local variables refer to objects on the heaplocal variables refer to objects on the heap
object
valueenum
class
interface
[ ]array
delegate
struct value
object
object
object
@
@
@
@
© { JSL }3838
stru
ct v
s cl
ass
stru
ct v
s cl
ass
struct Pair { int x, y; ...}
Pair p = new Pair(1,2);
Pair copy = p;
p.x
stack heap
class Pair { int x, y; ...}
Pair p = new Pair(1,2);
Pair copy = p;
1
2
@p
@copy
1
2
p.y
copy.x
copy.y
.x1
2 .y
© { JSL }3939
Ob
ject
s E
very
wh
ere
Ob
ject
s E
very
wh
ere
everythingeverything implicitly inherits from implicitly inherits from objectobject arrays,arrays, class classes, es, interfaceinterfaces, s, delegatedelegatess structstructs, s, enumenums, as wells, as well!!
System.Int32«struct»
System.ValueType«class»
System.Enum«class»
Suit«enum»
Pair«struct»
System.Object«class»
int == System.Int32
© { JSL }4040
Pro
ble
m?
Pro
ble
m?
a reference can bind to a valuea reference can bind to a value does the reference refer into the stack?does the reference refer into the stack? if so what happes when the scope ends?if so what happes when the scope ends?
struct Pair { public int X, Y; ...}
class Example{ static object Dangle() { Pair p = new Pair(1,2); object o = p; return o; }
static void Main() { object o = Dangle(); ... }}
p.X
stack
1
2
@o
p.Y
??
© { JSL }4141
Bo
xed
So
luti
on
Bo
xed
So
luti
on
when a reference variable binds to a valuewhen a reference variable binds to a value the runtime copies the value onto the heapthe runtime copies the value onto the heap the reference refers to the copy on the heapthe reference refers to the copy on the heap this is called boxingthis is called boxing
the copy is the same plain bitwise copy used for value parameters/returns
struct Pair { public int X, Y; ...}
static void Function(){ Pair p = new Pair(1,2);
object o = p;}
p.X
stack heap
1
2p.Y
.X1
2 .Y
@o
boxbox
© { JSL }4242
Un
bo
xin
gU
nb
oxi
ng
unboxing copies the boxed value back againunboxing copies the boxed value back again this requires an explicit cast to this requires an explicit cast to exactexact type type if the target type is wrong - InvalidCastExceptionif the target type is wrong - InvalidCastException
struct Pair { public int X, Y; ...}
static void Function(){ Pair p = new Pair(1,2);
object o = p;
p.X = p.Y = 0;
Pair q = (Pair)o;}
p.X
stack heap
0
0p.Y
.X1
2 .Y
@o
cast
q.X 1
2q.Y
boxbox
unboxunbox
© { JSL }4343
Sys
tem
.Ob
ject
Sys
tem
.Ob
ject
objectobject is an alias for System.Object is an alias for System.Object
namespace System{ public class Object { public Object(); public virtual bool Equals(object); public virtual int GetHashCode(); public Type GetType(); public virtual string ToString(); ... }}
static void AnySingleArgument(object accepted){ ...}
any value variable (implicit boxing)any reference variable (implicit conversion)
© { JSL }4444
No
Ove
rhea
dN
o O
verh
ead
in fact, value types do in fact, value types do notnot derive from derive from objectobject each value type has a hidden reference typeeach value type has a hidden reference type the hidden reference type holds the boxed valuethe hidden reference type holds the boxed value objectobject virtualvirtual method are not method are not overrideoverriden in valuesn in values they are they are overrideoverriden in the hidden reference typen in the hidden reference type
Pair« struct »
Object« class »
PairReference« class »
Int32Reference« class »
Int32« struct »
42.ToString() is not a virtual call
1 1
© { JSL }4545
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Inh
erit
ance
Inh
erit
ance
© { JSL }4646
Ext
ensi
on
Ext
ensi
on
like Java...like Java... a a classclass can inherit from a single can inherit from a single basebase classclass all inheritance is implicitly all inheritance is implicitly publicpublic
unlike Java...unlike Java... there is no extends keywordthere is no extends keyword by default methods are by default methods are notnot virtualvirtual a a structstruct cannot inherit from a cannot inherit from a structstruct or or class *class *
ViolinPlayer« class »
Musician« class »
class Musician{ public void NotVirtual()...}
class ViolinPlayer : Musician{ ...}
© { JSL }4747
: b
ase(
...)
: b
ase(
...)
a a classclass can call a sibling constructor can call a sibling constructor a a struct struct can toocan too
a a classclass can call its can call its basebase classclass constructor constructor a a structstruct can't (since it can't have a can't (since it can't have a basebase classclass))
class Musician{ public Musician(string name)... public void NotVirtual()...}
class ViolinPlayer : Musician{ public ViolinPlayer(string name) : base(name) { ... }}
© { JSL }4848
Met
ho
d A
cces
sM
eth
od
Acc
ess
two restrictionstwo restrictions a a privateprivate method cannot be method cannot be virtualvirtual a a structstruct can't declare a can't declare a protectedprotected member member
class GoodClass{ public virtual void Alpha()... protected virtual void Beta()... private void Gamma()...}class BadClass{ private virtual void Delta()...}struct GoodStruct{ public void Alpha()... private void Gamma()...}struct BadStruct{ protected void Beta()...}
© { JSL }4949
virt
ual
virt
ual
Met
ho
ds
Met
ho
ds
a a virtualvirtual method... method... introducesintroduces a method implementation a method implementation cannot be declared in a cannot be declared in a structstruct
class Musician{ ... public virtual void TuneUp() { ... }}
class ViolinPlayer : Musician{ public virtual void TuneUp() { ... }}
this does notoverride TuneUp from the Musician class
© { JSL }5050
ove
rrid
eo
verr
ide
Met
ho
ds
Met
ho
ds
an an overrideoverride method... method... specialisesspecialises an inherited identical an inherited identical virtualvirtual method method is implicitly is implicitly virtual virtual itselfitself cannot be declared in a cannot be declared in a struct struct **
class Musician{ ... public virtual void TuneUp() { ... }}
class ViolinPlayer : Musician{ public override void TuneUp() { ... }}
this does
same access too
© { JSL }5151
seal
edse
aled
Met
ho
ds
Met
ho
ds
a a sealed overridesealed override method... method... specialises an inherited identical specialises an inherited identical virtualvirtual method method which cannot itself be which cannot itself be overrideoverridenn cannot be declared in a cannot be declared in a structstruct
class Musician{ ... public virtual void TuneUp() { ... }}class ViolinPlayer : Musician{ public sealed override void TuneUp() { ... }}
sealed is always used with override
© { JSL }5252
new
Met
ho
ds
new
Met
ho
ds
a a newnew method... method... hides an identical inherited methodhides an identical inherited method can be used in combination with can be used in combination with virtualvirtual cannot be used in combination with cannot be used in combination with overrideoverride
class Musician{ ... public virtual void TuneUp() { ... }}
class ViolinPlayer : Musician{ public new virtual void TuneUp() { ... }}
© { JSL }5353
Tab
leT
able method modifiersmethod modifiers
structclass
override no*yes
sealed noyes
new no*yes
public yesyes
protected noyes
private yesyes
virtual noyes only needed whenoverriding or hiding methods from System.ValueType
© { JSL }5454
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Inte
rfac
esIn
terf
aces
© { JSL }5555
inte
rfac
ein
terf
ace
interfaces contain method signaturesinterfaces contain method signatures no access modifier, implicitly no access modifier, implicitly publicpublic no fields, not even no fields, not even staticstatic ones ones
interface names should start with an I
interface ITuneable{ void TuneUp();}
interface IPluckable{ void Pluck();}
IPluckable« interface »
ITuneable« interface »
© { JSL }5656
Mu
ltip
le In
terf
aces
Mu
ltip
le In
terf
aces
a a classclass can implement many can implement many interfaceinterfacess so can an so can an interfaceinterface so can a so can a struct struct (boxing)(boxing)
no implements keywordno implements keyword notation is positionalnotation is positional base base classclass first, then base first, then base interfaceinterfacess
class Violin : Instrument , IPluckable , ITuneable{ ...}
IPluckable« interface »
ITuneable« interface »
Violin« class »
Instrument« class »
© { JSL }5757
I.I.I.
I.I.I.
"implicit" interface implementation"implicit" interface implementation methods must be explicitly declared methods must be explicitly declared publicpublic by default methods are by default methods are notnot virtualvirtual
a class must implement all inherited interface methods
interface ITuneable{ void TuneUp();}
interface IPluckable{ void Pluck();}
class Violin : IPluckable, ITuneable{ public void TuneUp() { ... } public virtual void Pluck() { ... } ...}
© { JSL }5858
E.I.
I.E
.I.I. explicit interface implementationexplicit interface implementation
cannot have access modifier (cannot have access modifier (privateprivate-ish)-ish) cannot be cannot be virtualvirtual
interface ITuneable{ void TuneUp();}
interface IPluckable{ void Pluck();}
class Violin : Instrument , IPluckable, ITuneable{ void ITuneable.TuneUp() { ... } void IPluckable.Pluck() { ... } ...}
consider inheriting two operations with the same signature
you can mix III and EII
© { JSL }5959
inte
rfac
e P
rop
erty
inte
rfac
e P
rop
erty
an an interfaceinterface can declare a property can declare a property readwrite, readonly, writeonlyreadwrite, readonly, writeonly
interface IButton{ string Caption { get; set; } ...}
class Button : IButton{ public virtual string Caption { get { ... } set { ... } } ... private string caption;}
© { JSL }6060
inte
rfac
e In
dex
erin
terf
ace
Ind
exer
an an interfaceinterface can declare an indexer can declare an indexer readwrite, readonly, writeonlyreadwrite, readonly, writeonly indexers are not static operatorsindexers are not static operators
interface IDictionary{ string this [ string word ] { get; set; } ...}
class Dictionary : IDictionary{ public virtual string this [ string word ] { get { ... } set { ... } } ...}
© { JSL }6161
isis use use isis operator to check for type support operator to check for type support
returns returns truetrue or or falsefalse a cast can a cast can throwthrow an InvalidCastException an InvalidCastException
static void GreyHole(object o){ if (o is IPluckable) { IPluckable ip = (IPluckable)o; ip.Pluck() ... }}
static void Main(){ GreyHole(new Violin()); GreyHole(42);}
check once
check twice
cast
© { JSL }6262
asas
the the asas operator is similar operator is similar performs the conversion if the type is supportedperforms the conversion if the type is supported returns returns nullnull if its not if its not
static void GreyHole(object o){ IPluckable ip = o as IPluckable; if (ip != null) { ip.Pluck(); ... }}
static void Main(){ GreyHole(new Violin()); GreyHole(42);}
check once
© { JSL }6363
typ
eof
typ
eof
retrieving the exact type of an objectretrieving the exact type of an object System.Object.GetType() for variablesSystem.Object.GetType() for variables typeoftypeof for types known at compile time for types known at compile time Type.GetType() for types known at runtimeType.GetType() for types known at runtime
static void Main(){ Violin stradi = new Violin(); IPluckable ip = stradi;
Type t1 = ip.GetType(); Type t2 = typeof(Violin); Type t3 = Type.GetType("Violin");
Console.WriteLine(t1 == t2); Console.WriteLine(t2 == t3); Console.WriteLine((object)t1 == (object)t2); Console.WriteLine((object)t2 == (object)t3);}
TrueTrueTrueTrue
© { JSL }6464
ref
ou
tre
f o
ut
interfaceinterface parameters parameters can be can be refref qualified qualified can be can be outout qualified qualified
interface IPluckable{ void Pluck();}
static void Replace(ref IPluckable instrument){ instrument = new Guitar();}
static void Create(out IPluckable instrument){ instrument = new Banjo();}
© { JSL }6565
Tab
leT
able method modifiersmethod modifiers
structclass
override no*yes
sealed noyes
new no*yes
public yesyes
protected noyes
private yesyes
virtual noyes
i'face
no
no
yes
no
no
no
no
© { JSL }6666
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Ab
stra
ct C
lass
esA
bst
ract
Cla
sses
© { JSL }6767
abst
ract
Cla
sses
abst
ract
Cla
sses
an an abstractabstract classclass...... cannot be instantiatedcannot be instantiated can extend an can extend an abstractabstract class class or a or a classclass otherwise the same as a otherwise the same as a classclass
abstract class Bar{ ... private int instanceMethod() { ... } private int instanceField;}
abstract class Foo : Bar{ ... public static int StaticMethod() { ... } public static int StaticField;}
© { JSL }6868
abst
ract
Met
ho
ds
abst
ract
Met
ho
ds
an an abstractabstract method... method... can only be declared in an can only be declared in an abstractabstract classclass has no bodyhas no body cannot be cannot be privateprivate
abstract class Foo : Bar{ public abstract void Method(); ...}
© { JSL }6969
abst
ract
No
tes
abst
ract
No
tes
an an abstractabstract method... method... can can overrideoverride a inherited a inherited virtualvirtual method method must be implemented with the must be implemented with the samesame access access
abstract class Bar{ protected virtual void Method() { ... } ...}
abstract class Foo : Bar{ protected abstract override void Method(); ...}
© { JSL }7070
seal
ed C
lass
esse
aled
Cla
sses
a a sealedsealed classclass cannot be derived fromcannot be derived from cannot declare cannot declare virtual virtual methodsmethods cannot declare cannot declare abstractabstract methods methods structstructs and s and enumenums are implicitly s are implicitly sealedsealed
abstract class Foo : Bar{ protected abstract Method();}
sealed class Wibble : Foo{ protected override void Method() { ... } ...}
© { JSL }7171
Tab
leT
able method modifiersmethod modifiers
structclass
override no*yes
sealed noyes
new no*yes
public yesyes
protected noyes
private yesyes
virtual noyes
i'face
no
no
yes
no
no
no
no
abstract
yes
yes
yes
yes
yes
no
yes
sealed
yes
yes
yes
yes
yes
yes
no
abstract nonono yes no
© { JSL }7272
An
oth
er T
able
An
oth
er T
able
method modifier combinationsmethod modifier combinations
override
new
sealed
virtual
1
2
N
N
abstract •
ab
stra
ct
N
3
N
•
vir
tua
l
•
N
4
ov
erri
de
•
N
ne
w
•
sea
led
modifier order isnot significant
© { JSL }7373
C# ProgrammingC# Programming
Exc
epti
on
sE
xcep
tio
ns
Fundamentals
Objects
Relationships
Systems
© { JSL }7474
Sys
tem
.Exc
epti
on
Sys
tem
.Exc
epti
on
the root of all Exception clasasesthe root of all Exception clasases
namespace System{ public class Exception ... { public Exception(); public Exception(string); public Exception(string, Exception); ... public Exception InnerException { get; } public virtual string Message { get; } public virtual string StackTrace { get; } ... public override string ToString(); ... }}
© { JSL }7575
Hie
rarc
hy
Hie
rarc
hy
Exception
ArithmeticException
InvalidCastException
DivideByZeroException
OutOfMemoryException
NullReferenceException
OverflowException
SystemException
...
ExecutionEngineException
IndexOutOfRangeException
© { JSL }7676
thro
wth
row
you can you can throwthrow any object you like any object you like as long as it's derived from System.Exceptionas long as it's derived from System.Exception
class Matrix { public Matrix(int rowSize, int colSize) { ... }
public Row this [ int index ] { get { BoundsCheck(index); ... } set { BoundsCheck(index); ... } } // validation private void BoundsCheck(int index) { if (index < 0 || index >= rows.Length) throw new IndexOutOfRangeException(); } // representation private Row[] rows;}
don't forget the new
© { JSL }7777
try
catc
htr
y ca
tch
you can separate out error handling codeyou can separate out error handling code in a in a catchcatch { block } after a { block } after a trytry { block } { block } goodbye HRESULTgoodbye HRESULT
try { FileInfo source = new FileInfo(filename); int length = (int)source.Length; char[] contents = new char[length]; ...}catch (SecurityException caught) { ... }catch (IOException caught) { ... }catch (OutOfMemoryException) { ... }catch { ... throw; }
name isoptional
generalcatchblock
© { JSL }7878
fin
ally
fin
ally
you can ensure code always runsyou can ensure code always runs in a in a finallyfinally { block } { block } exception in exception in finallyfinally block dominates block dominates you cannot jump out of a you cannot jump out of a finallyfinally block block
TextReader reader = null;try { FileInfo source = new FileInfo(filename); int length = (int)source.Length; char[] contents = new char[length]; reader = source.OpenText(); reader.Read(contents, 0, length); ...}...finally { if (reader != null) { reader.Close(); } }
definite assignment rules, OK
© { JSL }7979
Lo
cal R
eso
urc
esL
oca
l Res
ou
rces
deterministic finalisation via deterministic finalisation via finallyfinally...... is exception safe, but...is exception safe, but... is repetitive and doesn't scaleis repetitive and doesn't scale is complex and fails to abstractis complex and fails to abstract
TextReader reader = null;try { FileInfo source = new FileInfo(filename); int length = (int)source.Length; char[] contents = new char[length]; reader = source.OpenText(); reader.Read(contents, 0, length); ...}...finally { if (reader != null) { reader.Close(); } }
© { JSL }8080
usi
ng
Sta
tem
ents
usi
ng
Sta
tem
ents
after discussions on the .NET reflectorafter discussions on the .NET reflector M'Soft provided a solution consisting of...M'Soft provided a solution consisting of... the IDisposable the IDisposable interfaceinterface in combination with... in combination with... the the usingusing statement statement
using (type variable = init) embedded-statement
{ type variable = init; try { embedded-statement } finally { if (variable != null) { ((IDisposable)variable).Dispose(); } }}
precisely equivalent to
© { JSL }8181
IDis
po
sab
leID
isp
osa
ble
struct AutoClosing : IDisposable{ public AutoClosing(TextReader reader) { if (reader == null) { throw new ArgumentNullException(); } target = reader; } public void Dispose() { target.Close(); } private readonly TextReader target;}
interface IDisposable{ void Dispose();}
© { JSL }8282
Pre
fere
nce
?P
refe
ren
ce?
...TextReader reader = source.OpenText();using (new AutoClosing(reader)){ reader.Read(contents, 0, length); ...}
TextReader reader = null;try { ... reader = source.OpenText(); reader.Read(contents, 0, length); ...}finally { if (reader != null) { reader.Close(); } }
Before...
...After
© { JSL }8383
lock
lock
C# does not have a synchronize keywordC# does not have a synchronize keyword it has it has locklock statements statements
public class Monitor{ public static void Enter(object); public static void Exit(object); ...}
lock (expression) embedded-statement
System.Threading.Monitor.Enter(expression);try { embedded-statement}finally { System.Threading.Monitor.Exit(expression);}
precisely equivalent to (expression is evaluated once)
© { JSL }8484
Exc
epti
on
No
tes
Exc
epti
on
No
tes
throw specifications - NOthrow specifications - NO checked/unchecked distinction - NOchecked/unchecked distinction - NO compile time exceptions - NOcompile time exceptions - NO
© { JSL }8585
C# ProgrammingC# Programming
Gar
bag
e C
olle
ctio
nG
arb
age
Co
llect
ion
Fundamentals
Objects
Relationships
Systems
© { JSL }8686
Th
e M
irac
le o
f B
irth
Th
e M
irac
le o
f B
irth
objectobject birth is a two phase process birth is a two phase process allocate the raw memoryallocate the raw memory
using operator using operator newnew { 1,2,3,4 } is an [ ]array shorthand{ 1,2,3,4 } is an [ ]array shorthand "literal" is a "literal" is a stringstring shorthand shorthand
initialise an object in the memoryinitialise an object in the memory using a constructorusing a constructor you can't use a constructor without you can't use a constructor without newnew
Get that would you, Deidre....
© { JSL }8787
Dea
thD
eath objectobject death is a two phase process death is a two phase process
finalise the object back to raw memoryfinalise the object back to raw memory deallocate the raw memory back to the heapdeallocate the raw memory back to the heap
C++ – deterministicC++ – deterministic user calls destructoruser calls destructor user calls operator deleteuser calls operator delete
C# – non deterministic (like Java)C# – non deterministic (like Java) GC calls FinalizeGC calls Finalize GC reclaims heap memory GC reclaims heap memory
Shall we take our cars?
© { JSL }8888
Fin
aliz
eF
inal
ize
garbage collector finalizes objectsgarbage collector finalizes objects when they become unreachablewhen they become unreachable by calling Finalize( )by calling Finalize( ) but you cannot but you cannot overrideoverride Object.Finalize!! Object.Finalize!! or call itor call it
public class Resource { ... public void Dispose() { this.Finalize(); }
protected override void Finalize() { ... }}
compile time errors
© { JSL }8989
Des
tru
cto
rD
estr
uct
or
instead you write a destructorinstead you write a destructor which the compiler translates into Finalizewhich the compiler translates into Finalize can be declared in a can be declared in a classclass but not a but not a structstruct automatically calls its automatically calls its basebase class Finalize class Finalize can can onlyonly be called by garbage collector be called by garbage collector
public class Resource { ... ~Resource() { //... } ...}
public class Resource { ... protected override void Finalize() { //... base.Finalize(); } ...}
© { JSL }9090
GC
No
tes
GC
No
tes
Beta-2Beta-2 destructors destructors areare called when program exits :-) called when program exits :-) API to toggle this behavior :-)API to toggle this behavior :-) Finalize can make Finalize can make thisthis known again known again
complex resurrection issues, slows GC :-(complex resurrection issues, slows GC :-( what happens if Finalize throws ?what happens if Finalize throws ?
specification doesn't say :-(specification doesn't say :-(
© { JSL }9191
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Nes
ted
Typ
esN
este
d T
ypes
© { JSL }9292
Nes
ted
Typ
esN
este
d T
ypes
a a classclass or or structstruct can declare nested types can declare nested types nested types default to nested types default to private private accessaccess non-nested types default to non-nested types default to internalinternal access access
class Outer{ interface Space { } abstract class Reaches { } class Limits { } sealed class Hebrides { } struct Mongolia { }}
internal access
private access
© { JSL }9393
Nes
ted
Acc
ess
Nes
ted
Acc
ess
a nested type...a nested type... has access to all members of outer typeshas access to all members of outer types but not vice versabut not vice versa C# follows Java access modelC# follows Java access model
class Outer{ public class Inner { private void peek(Outer can) { can.peek(this); } } private void peek(Inner cannot) { cannot.peek(this); }}
OKFails
Outer.peek(Inner cannot)Inner.peek(Outer can)
© { JSL }9494
Acc
ess
Mo
dif
iers
Acc
ess
Mo
dif
iers
there are five kinds of accessthere are five kinds of access nested types can have any access modifiernested types can have any access modifier non-nested types can be non-nested types can be publicpublic or or internalinternal
internal
protected internal
private
protected
Y
public Y
no
n-n
es
ted
Y
Y
Y
Y
ne
ste
d
Y
protectedORinternal
© { JSL }9595
Sem
anti
csS
eman
tics
C# nested types are implicitly C# nested types are implicitly staticstatic C# does not have Java inner classes C# does not have Java inner classes C# does not have Java local classesC# does not have Java local classes C# does not have Java anonymous classesC# does not have Java anonymous classes
class Outer{ ... class Nested { ... } ... }
Outer.Nested« class »
Outer« class »
Outer$Inner« class »
Outer« class » Outer.this
1
C#, C++
Java
© { JSL }9696
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Del
egat
esD
eleg
ates
© { JSL }9797
del
egat
e T
ype
del
egat
e T
ype
a a delegatedelegate is the last C# type... is the last C# type... declares a named signature including return typedeclares a named signature including return type like a C++ function pointer/objectlike a C++ function pointer/object similar to a Delphi closuresimilar to a Delphi closure
delegate void Func(string s);
class Eg{ public static void ForAll(string[] args, Func call) { foreach (string arg in args) { call(arg); } }}
Func is a type name
© { JSL }9898
stat
ic M
eth
od
stat
ic M
eth
od
a a delegatedelegate instance... instance... can hold and call a can hold and call a staticstatic method method
delegate void Func(string s);...class Test{ static void Display(string s) { ... }
static void Main(string[] args) { Eg.ForAll(args, new Func(Test.Display)); Eg.ForAll(args, new Func(Display)); }}
note no ( )
create a delegate instance
© { JSL }9999
Inst
ance
Met
ho
dIn
stan
ce M
eth
od
a a delegatedelegate instance... instance... can hold and call an instance methodcan hold and call an instance method
delegate void Func(string s);...class Test{ void Stash(string s) { ... }
void NotMain(string[] args) { Eg.ForAll(args, new Func(this.Stash)); Eg.ForAll(args, new Func(Stash)); }}
© { JSL }100100R
emem
ber
Th
is?
Rem
emb
er T
his
?
delegate void Method();...TextReader reader = source.OpenText();using (new Finally(new Method(reader.Close))){ reader.Read(contents, 0, length); ...}
TextReader reader = null;try { ... reader = source.OpenText(); reader.Read(contents, 0, length); ...}finally { if (reader != null) { reader.Close(); } }
...After
Before...
© { JSL }101101F
inal
lyF
inal
ly
public delegate void Method();
public struct Finally : IDisposable{ public Finally(Method call) { if (call == null) { throw new ArgumentNullException(); } this.call = call; } public override void Dispose() { call(); } private readonly Method call;}
© { JSL }102102M
ulit
cast
del
egat
eM
ulit
cast
del
egat
e a a voidvoid return type return type delegatedelegate... ...
can hold multiple callback in its invocation listcan hold multiple callback in its invocation list first in, first calledfirst in, first called
delegate void Pred(string s);...class Test{ void DoThis(string s) { ... }
static void ThenThat(string s) { ... }
void Method(string arg) { Pred call = null; call += new Pred(this.DoThis); call += new Pred(Test.ThenThat); ... call(arg); }}
© { JSL }103103d
eleg
ate
No
tes
del
egat
e N
ote
s delegatesdelegates
are called directly from invokers threadare called directly from invokers thread can be compared for equalitycan be compared for equality can be can be refref and and outout parameters parameters are implicitly sealed typesare implicitly sealed types
combinable delegatecombinable delegate voidvoid return type return type implicitly derive from System.Delegateimplicitly derive from System.Delegate
non-combinable delegatenon-combinable delegate non non voidvoid return type return type no no outout parameters parameters implicitly derive from System.MultiCastDelegateimplicitly derive from System.MultiCastDelegate
© { JSL }104104
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Eve
nts
Eve
nts
© { JSL }105105ev
ent
Del
egat
esev
ent
Del
egat
es a a delegatedelegate field can be marked as an field can be marked as an eventevent
onlyonly += and += and -=-= can be performed on the field can be performed on the field used widely in GUI classesused widely in GUI classes
namespace System.Windows.Forms{ public class Button : ... { ... public event EventHandler Click; ... ... protected void OnClick(EventArgs e) { if (Click != null) { Click(this, e); } } ... }}
© { JSL }106106E
ven
t D
eleg
ates
Eve
nt
Del
egat
es .NET framework has many .NET framework has many eventevent delegatesdelegates
by convention first parameter is event senderby convention first parameter is event sender and second parameter derives from EventArgsand second parameter derives from EventArgs
namespace System{ public delegate void EventHandler ( object sender, EventArgs e ); ... public class EventArgs { ... }}
© { JSL }107107E
ven
t E
xam
ple
Eve
nt
Exa
mp
le easy to imagine this in Java...easy to imagine this in Java...
using an anonymous classusing an anonymous class
using System;using System.Windows.Forms;
class MyForm : Form{ private void InitializeComponent() { openFile = new Button(); ... openFile.Click += new EventHandler(OpenFile); }
protected void OpenFile(object sender, EventArgs e) { ... }
private Button openFile;}
Note case difference: openFile vs OpenFile
© { JSL }108108E
ven
t P
rop
erti
esE
ven
t P
rop
erti
es eventevent fields can be exposed as properties fields can be exposed as properties
consider a consider a classclass with lots of with lots of eventeventss lazy creation might be usefullazy creation might be useful += forwards to += forwards to addadd -=-= forwards to forwards to removeremove
namespace System.Windows.Forms{ public class Button : ... { ... public event EventHandler Click { add { ... } remove { ... } } ... }}
© { JSL }109109
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Nam
esp
aces
Nam
esp
aces
© { JSL }110110n
ames
pac
en
ames
pac
e a namespace is a logical naming mechanisma namespace is a logical naming mechanism
no relation to directory names or assembliesno relation to directory names or assemblies a single .cs file can declare several namespacesa single .cs file can declare several namespaces implicitly implicitly publicpublic handy shorthandhandy shorthand no anonymous namespaceno anonymous namespace
namespace Accu{ namespace Conference { ... }}namespace Informant{ ...}
namespace Accu.Conference{ ... ... ... ...}namespace Informant{ ...}
© { JSL }111111u
sin
g D
irec
tive
usi
ng
Dir
ecti
ve only allowed at the start of namespaceonly allowed at the start of namespace
respect scope, not recursive, no clash if no userespect scope, not recursive, no clash if no use never affect other never affect other usingusing directives directives
using System;
class Bar { ... }
namespace Accu.Conference{ using System.Collections; ... class Foo : Bar { static void Main(String[] args) { Console.Write(args[0]); } ... private Hashtable store; } }
© { JSL }112112u
sin
g A
lias
usi
ng
Alia
s a a usingusing alias creates alias for... alias creates alias for...
a namespace, ora namespace, or a typea type
namespace CSharp{ using Vector = System.Collections.ArrayList; class SourceFile { ... Vector tokens; }}
© { JSL }113113N
ames
pac
e N
ote
sN
ames
pac
e N
ote
s usingusing
only at start of namespaceonly at start of namespace respects scoperespects scope never affect subsequent using directivesnever affect subsequent using directives never affect subsequent using aliasesnever affect subsequent using aliases
namespacenamespace top level, non nested classestop level, non nested classes publicpublic or or internalinternal, default to , default to internalinternal cannot be cannot be protectedprotected or or privateprivate
© { JSL }114114
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Ass
emb
lies
Ass
emb
lies
© { JSL }115115M
od
ule
sM
od
ule
s a physical .NET .DLL a physical .NET .DLL
contains types and MSIL codecontains types and MSIL code unit of dynamic downloadunit of dynamic download
a PE (portable executable) file written usinga PE (portable executable) file written using C#, VB.NET, managed C++, raw MSIL, others...C#, VB.NET, managed C++, raw MSIL, others... but not a mixturebut not a mixture
C:\> csc ... /target:module ...
© { JSL }116116A
ssem
bly
Ass
emb
ly a logical .NET .DLL containing...a logical .NET .DLL containing...
manifest containing metadatamanifest containing metadata name, version#, file-listname, version#, file-list referenced assembliesreferenced assemblies type-list type-list containing module containing module security permissionssecurity permissions
one or more modules containing typesone or more modules containing types one containing assembly entry pointone containing assembly entry point
zero or more resourceszero or more resources bitmaps, icons, etcbitmaps, icons, etc
physically or logicallycontaining
C:\> csc ... /target:library ...C:\> csc ... /addmodule:... C:\> csc ... /target:exe /reference:...
© { JSL }117117D
eplo
ymen
tD
eplo
ymen
t to deploy an assembly...to deploy an assembly...
drop it and its linked files into a drop it and its linked files into a singlesingle directory directory goodbye registrygoodbye registry
private assemblies...private assemblies... live in their application's directorylive in their application's directory are not versionedare not versioned
shared assemblies...shared assemblies... live in a shared directory (Global Assembly Cache)live in a shared directory (Global Assembly Cache) are versionedare versioned need a shared name (aka strong name)need a shared name (aka strong name)
textual nametextual name public keypublic key digital signaturedigital signature
© { JSL }118118V
ersi
on
ing
Ver
sio
nin
g assemblies with different versions co-existassemblies with different versions co-exist
allows assembly evolution managementallows assembly evolution management never modify an existing assemblynever modify an existing assembly instead, create a new assembly with a new versioninstead, create a new assembly with a new version
<major>.<minor>.<build>.<revision>
incompatible maybecompatible
QuickFixEngineering
© { JSL }119119V
ersi
on
Po
licy
Ver
sio
n P
olic
y update policy controlled via .XML text fileupdate policy controlled via .XML text file
defaultdefault major.minor as builtmajor.minor as built
specificspecific major.minor as specifiedmajor.minor as specified
QFEQFE latest build.revision?latest build.revision?
safesafe exactly as builtexactly as built
...<BindingPolicy> <BindingRedir Name="Wibble" Originator="32ab4ba45e0a69a1" Version="*" VersionNew="6.1.1212.14" UseLatestBuildRevision="no"/></BindingPolicy>
© { JSL }120120in
tern
al a
cces
sin
tern
al a
cces
s logical access controllogical access control
public, protected, privatepublic, protected, private
physical access controlphysical access control internal internal access is within assemblyaccess is within assembly
public
internal
private
an assemblyof four classes
© { JSL }121121
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
[Att
rib
ute
s][A
ttri
bu
tes]
© { JSL }122122W
hat
Are
Th
ey?
Wh
at A
re T
hey
? attributes allow code elements to...attributes allow code elements to...
be tagged with declarative informationbe tagged with declarative information which is then added to the metadatawhich is then added to the metadata which can queried using reflectionwhich can queried using reflection
for example...for example... suppose you wanted to record which developers suppose you wanted to record which developers
implemented which typesimplemented which types ...... create a class to represent the developer infocreate a class to represent the developer info tag types with the developer attributetag types with the developer attribute specify developer attribute is only for typesspecify developer attribute is only for types decide whether to allow multiple tagsdecide whether to allow multiple tags
© { JSL }123123A
ttri
bu
te C
lass
Att
rib
ute
Cla
ss create attribute classcreate attribute class
must derive from System.Attributemust derive from System.Attribute recommedation – use Attribute suffix in namerecommedation – use Attribute suffix in name
...public sealed class DeveloperAttribute : System.Attribute{ ... public DeveloperAttribute(string name) { ... } ...}
© { JSL }124124[
tag
]
[ ta
g ]
tag code elements with [attribute]'stag code elements with [attribute]'s
ConstInt struct is tagged [ DeveloperAttribute ]ConstInt struct is tagged [ DeveloperAttribute ]
[DeveloperAttribute("Jon Jagger")]
public struct ConstInt{ public ConstInt(int value) { this.value = value; }
public static implicit operator int(ConstInt from) { return from.value; }
private readonly int value;}
© { JSL }125125P
rob
lem
Pro
ble
m how can you specify which kind of code how can you specify which kind of code
elements the attribute is to be used with?elements the attribute is to be used with? Assembly, ModuleAssembly, Module Interface, Class, Struct, Enum, DelegateInterface, Class, Struct, Enum, Delegate Constructor, Method, Property, Field, EventConstructor, Method, Property, Field, Event Parameter, ReturnValueParameter, ReturnValue AllAll
© { JSL }126126A
ttri
bu
teU
sag
eA
ttri
bu
teU
sag
e use a predefined AttributeUsage attribute!use a predefined AttributeUsage attribute!
with AttributeTarget enumwith AttributeTarget enum
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)]
public sealed class DeveloperAttribute : System.Attribute{ ... public DeveloperAttribute(string name) { ... } ...}
© { JSL }127127M
ult
iple
Tag
sM
ult
iple
Tag
s decide whether to allow multiple tagsdecide whether to allow multiple tags
use named parameter, AllowMultiple = true use named parameter, AllowMultiple = true
[AttributeUsage(AttributeTargets.Class | ..., AllowMultiple = true)]
public sealed class DeveloperAttribute : System.Attribute{ ... public DeveloperAttribute(string name) { ... } ...}
[DeveloperAttribute("Jon Jagger")][DeveloperAttribute("Patrick Jagger")]public struct ConstInt{ ...}
© { JSL }128128P
osi
tio
nal
Po
siti
on
al positional parameterspositional parameters
must be specified in the attribution must be specified in the attribution correspond to constructor argumentscorrespond to constructor arguments
...public sealed class DeveloperAttribute : System.Attribute{ public DeveloperAttribute(string name) { ... } ...}
[DeveloperAttribute("Jon Jagger")]
public struct ConstInt{ ...}
© { JSL }129129N
amed
Nam
ed named parametersnamed parameters
optionally specified in the attribution optionally specified in the attribution must correspond to fields/propertiesmust correspond to fields/properties
(non-(non-staticstatic, , publicpublic, read-write), read-write)
...public sealed class DeveloperAttribute : System.Attribute{ public DeveloperAttribute(string name) ... ... public string TelExt { get {...} set {...} }}
[DeveloperAttribute("Patrick Jagger")][DeveloperAttribute("Jon Jagger", TelExt="4263")]
public struct ConstInt { ... }
© { JSL }130130m
etad
ata
met
adat
a attributes are added to assembly metadataattributes are added to assembly metadata
visible though ILDASM or reflectionvisible though ILDASM or reflection
© { JSL }131131N
ote
sN
ote
s attributes are checked at compile timeattributes are checked at compile time
incorrect usage causes compile time error incorrect usage causes compile time error predefined attribute classes includepredefined attribute classes include
[Conditional][Conditional] [Obsolete][Obsolete] [CLSCompliant][CLSCompliant] [Serializable][Serializable]
attribute parameter types limited toattribute parameter types limited to bool, byte, char, double, float, int, long, shortbool, byte, char, double, float, int, long, short string, objectstring, object public enumspublic enums TypeType
CLS attribute based templates CLS attribute based templates check out check out www.newtelligence.comwww.newtelligence.com
© { JSL }132132
C# ProgrammingC# Programming
Fundamentals
Objects
Relationships
Systems
Ref
lect
ion
Ref
lect
ion
© { JSL }133133T
erm
ino
log
yT
erm
ino
log
y .NET has almost perfect reflection.NET has almost perfect reflection
reflection API's even allow dynamic creationreflection API's even allow dynamic creation
Reflection is the ability of a program to manipulate as data something representing the state of the program during its own execution. There are two apects to such manipulation:
Introspection is the ability of a program to observe and therefore reason about its own state.
Intercession is the ability of a program to modify its own execution state or alter its own interpretation or meaning. Both apects require a mechanism for encoding execution state as data; providing such an encoding is called reification
Richard Gabriel, et al
© { JSL }134134A
ttri
bu
tes
Att
rib
ute
s retrieving custom attributesretrieving custom attributes
public sealed class DeveloperAttribute ...{ ... public override string ToString() { ... } ...}
public class Example{ static void Main() { string typename = "ConstInt"; Type t = Type.GetType(typename); object[] atts = t.GetCustomAttributes(true); foreach (object att in atts) { Console.WriteLine(att); } } }
© { JSL }135135R
emem
ber
Th
is?
Rem
emb
er T
his
?
TextReader reader = source.OpenText();using (new Finally(reader, "Close")){ reader.Read(contents, 0, length); ...}
TextReader reader = null;try { ... reader = source.OpenText(); reader.Read(contents, 0, length); ...}finally { if (reader != null) { reader.Close(); } }
...After
© { JSL }136136F
inal
lyF
inal
lyusing System;using System.Reflection;
public struct Finally : IDisposable{ public Finally(object target, string methodName) { this.target = target; this.methodName = methodName; } public void Dispose() { Type t = target.GetType(); MethodInfo method = t.GetMethod(methodName); if (method != null) { t.InvokeMember( methodName, BindingFlags.InvokeMethod, target, new object[0] ); } } private readonly object target; private readonly string methodName;}
© { JSL }137137S
um
mar
yS
um
mar
y arrays: rectangular, ragged, paramsarrays: rectangular, ragged, params string: immutable, readonly[], verbatimstring: immutable, readonly[], verbatim class: ref/out, static c'tor, boxingclass: ref/out, static c'tor, boxing exceptions: lock, no throw-specsexceptions: lock, no throw-specs GC: d'tor, using statement, IDisposableGC: d'tor, using statement, IDisposable inheritance: positional, virtual/overrideinheritance: positional, virtual/override interfaces: no fields, EII, properties, indexersinterfaces: no fields, EII, properties, indexers nested types: Java access, C++ semanticsnested types: Java access, C++ semantics delegates: function pointers, single and multicastdelegates: function pointers, single and multicast events: restricted multicast delegateevents: restricted multicast delegate assemblies: logical DLL, no registry, versioningassemblies: logical DLL, no registry, versioning namespaces: shorthand syntaxnamespaces: shorthand syntax reflection: metadata, introspection, intercessionreflection: metadata, introspection, intercession attributes: add to metadata, reflectattributes: add to metadata, reflect
© { JSL }138138S
tan
dar
ds
Sta
nd
ard
s ECMA/TC39/2000-2ECMA/TC39/2000-2
Standard 1, C#Standard 1, C# Standard 2, Common Language InfrastructureStandard 2, Common Language Infrastructure
TimelineTimeline March 2001 – draft submissionMarch 2001 – draft submission Sept 2001 – final submissionSept 2001 – final submission Dec 2001 – Version 1 adopted by GADec 2001 – Version 1 adopted by GA Jan 2002 – submit to ISO for fast track processJan 2002 – submit to ISO for fast track process
© { JSL }139139B
iblio
gra
ph
yB
iblio
gra
ph
y Presenting C#Presenting C#
Christophe Wille; SAMSChristophe Wille; SAMS
A Programmer's Introduction to C#A Programmer's Introduction to C# Eric Gunnerson; ApressEric Gunnerson; Apress
Programming C# with the public BetaProgramming C# with the public Beta Harvey, Robinson,Templeman, Watson; WroxHarvey, Robinson,Templeman, Watson; Wrox
C# EssentialsC# Essentials Albahari, Drayton, Merrill; O'ReillyAlbahari, Drayton, Merrill; O'Reilly
Inside C#Inside C# Tom Archer; MS PressTom Archer; MS Press