Notes
Outline
C# in Detail
Blatant Advert
Agenda
string
class
constructors
fields
parameters
arrays
boxing
exceptions
garbage collection
inheritance, interfaces, abstract classes
nested types
delegates and events
namespaces
assemblies
attributes
reflection
string
string Type
string is a reference type
the only one with a literal syntax
immutable; just like in Java
indexer
string has a readonly indexer
integer index is always bounds checked
throws ArgumentOutOfRangeException
System.String
string is an alias for System.String
StringBuilder
System.Text.StringBuilder
string Literals
usual syntax
embedded escape chars, but no octal
unusual syntax
@ verbatim string literals
string Operators
equality operators are overloaded
they compare the values not the references
relational operators are not overloaded
binary + is overloaded, forwards to .Concat
operator += too
class
class Declaration
a user-defined reference type
object Creation
a class local variable lives on the stack
is not definitely assigned
can be initialised with null or a c'tor call
class Constructor
usual class rules
compiler declares a default c'tor
you can declare the default c'tor
if you declare a c'tor the compiler doesn't
: this(...)
a c'tor can call a sibling c'tor
syntax is a cross between C++ and Java
no general member-init-list syntax though
instance Fields
instance fields...
are default initialised by default in all c'tors
can be initialised in variable initialiser
can be explicitly initialised in a c'tor
readonly Fields
readonly instance fields...
are instance fields that cannot be assigned to
const Fields
const fields are implicitly static
only simple types, enums, & string can be const
const fields require a variable initializer
static Fields
to declare static fields of other types
use static keyword!
static fields are default initialised
static fields can use variable initialisers
access is via typename only
static Constructor
a static c'tor initialises the type
can initialize static fields but not const fields
called by VES when the type is loaded
cannot be called, no access modifier allowed
Copy Parameters
a plain parameter is a copy of the argument
no frills bitwise copy
the argument must be definitely assigned
argument can be an "rvalue"
ref Parameters
a ref parameter is an alias for the argument
no copy takes place
argument must be definitely assigned
argument must be an "lvalue"
ref required on argument and parameter
out Parameters
an out parameter is an alias for the argument
no copy takes places
argument need not be definitely assigned
parameter must be definitely assigned
argument must be an "lvalue"
out required on argument and parameter
in Parameters?
readonly, const, and in, are all C# keywords
they cannot be applied to parameters
reference types always grant write access
[ ] Arrays
Array Variables
C# supports rectangular arrays
rectangular arrays are reference types
Array Instances
array instances are created using new
rectangular arrays must specify all dimensions
array instance elements are default initialised
Array Initialisation
arrays can be initialised
omitted initialisers are not permitted
array size may be omitted
standard shortcut notation
System.Array
all array types inherit from System.Array
Using Arrays
all array access is bounds checked
throws IndexOutOfRangeException
Ragged Arrays
C# also supports ragged arrays
arrays of arrays
array instance still created using new
Ragged Initialisation
each sub array can be intialised as before
you can only specify the first dimension
params type[ ]
C# supports variadic functions
params keyword can be used on array parameter
only on a single dimension array parameter
params object[ ]
params with object as the element type
creates a truly variadic function
thanks to boxing
Array Notes
Boxing
Recap
value types
variables contain their own data directly
local variables always live on the stack
reference types
variables refer to their data indirectly
local variables refer to objects on the heap
struct vs class
Objects Everywhere
everything implicitly inherits from object
arrays, classes, interfaces, delegates
structs, enums, as well!
Problem?
a reference can bind to a value
does the reference refer into the stack?
if so what happes when the scope ends?
Boxed Solution
when a reference variable binds to a value
the runtime copies the value onto the heap
the reference refers to the copy on the heap
this is called boxing
Unboxing
unboxing copies the boxed value back again
this requires an explicit cast to exact type
if the target type is wrong - InvalidCastException
System.Object
object is an alias for System.Object
No Overhead
in fact, value types do not derive from object
each value type has a hidden reference type
the hidden reference type holds the boxed value
object virtual method are not overriden in values
they are overriden in the hidden reference type
Inheritance
Extension
like Java...
a class can inherit from a single base class
all inheritance is implicitly public
unlike Java...
there is no extends keyword
by default methods are not virtual
a struct cannot inherit from a struct or class *
: base(...)
a class can call a sibling constructor
a struct can too
a class can call its base class constructor
a struct can't (since it can't have a base class)
Method Access
two restrictions
a private method cannot be virtual
a struct can't declare a protected member
virtual Methods
a virtual method...
introduces a method implementation
cannot be declared in a struct
override Methods
an override method...
specialises an inherited identical virtual method
is implicitly virtual itself
cannot be declared in a struct *
sealed Methods
a sealed override method...
specialises an inherited identical virtual method
which cannot itself be overriden
cannot be declared in a struct
new Methods
a new method...
hides an identical inherited method
can be used in combination with virtual
cannot be used in combination with override
Table
method modifiers
Interfaces
interface
interfaces contain method signatures
no access modifier, implicitly public
no fields, not even static ones
Multiple Interfaces
a class can implement many interfaces
so can an interface
so can a struct (boxing)
no implements keyword
notation is positional
base class first, then base interfaces
I.I.I.
"implicit" interface implementation
methods must be explicitly declared public
by default methods are not virtual
E.I.I.
explicit interface implementation
cannot have access modifier (private-ish)
cannot be virtual
interface Property
an interface can declare a property
readwrite, readonly, writeonly
interface Indexer
an interface can declare an indexer
readwrite, readonly, writeonly
indexers are not static operators
is
use is operator to check for type support
returns true or false
a cast can throw an InvalidCastException
as
the as operator is similar
performs the conversion if the type is supported
returns null if its not
typeof
retrieving the exact type of an object
System.Object.GetType() for variables
typeof for types known at compile time
Type.GetType() for types known at runtime
ref out
interface parameters
can be ref qualified
can be out qualified
Table
method modifiers
Abstract Classes
abstract Classes
an abstract class...
cannot be instantiated
can extend an abstract class or a class
otherwise the same as a class
abstract Methods
an abstract method...
can only be declared in an abstract class
has no body
cannot be private
abstract Notes
an abstract method...
can override a inherited virtual method
must be implemented with the same access
sealed Classes
a sealed class
cannot be derived from
cannot declare virtual methods
cannot declare abstract methods
structs and enums are implicitly sealed
Table
method modifiers
Another Table
method modifier combinations
Exceptions
System.Exception
the root of all Exception clasases
Hierarchy
throw
you can throw any object you like
as long as it's derived from System.Exception
try catch
you can separate out error handling code
in a catch { block } after a try { block }
goodbye HRESULT
finally
you can ensure code always runs
in a finally { block }
exception in finally block dominates
you cannot jump out of a finally block
Local Resources
deterministic finalisation via finally...
is exception safe, but...
is repetitive and doesn't scale
is complex and fails to abstract
using Statements
after discussions on the .NET reflector
M'Soft provided a solution consisting of...
the IDisposable interface in combination with...
the using statement
IDisposable
Preference?
lock
C# does not have a synchronize keyword
it has lock statements
Exception Notes
throw specifications - NO
checked/unchecked distinction - NO
compile time exceptions - NO
Garbage Collection
The Miracle of Birth
object birth is a two phase process
allocate the raw memory
using operator new
{ 1,2,3,4 } is an [ ]array shorthand
"literal" is a string shorthand
initialise an object in the memory
using a constructor
you can't use a constructor without new
Death
object death is a two phase process
finalise the object back to raw memory
deallocate the raw memory back to the heap
C++ – deterministic
user calls destructor
user calls operator delete
C# – non deterministic (like Java)
GC calls Finalize
GC reclaims heap memory
Finalize
garbage collector finalizes objects
when they become unreachable
by calling Finalize( )
but you cannot override Object.Finalize!!
or call it
Destructor
instead you write a destructor
which the compiler translates into Finalize
can be declared in a class but not a struct
automatically calls its base class Finalize
can only be called by garbage collector
GC Notes
Beta-2
destructors are called when program exits :-)
API to toggle this behavior :-)
Finalize can make this known again
complex resurrection issues, slows GC :-(
what happens if Finalize throws ?
specification doesn't say :-(
Nested Types
Nested Types
a class or struct can declare nested types
nested types default to private access
non-nested types default to internal access
Nested Access
a nested type...
has access to all members of outer types
but not vice versa
C# follows Java access model
Access Modifiers
there are five kinds of access
nested types can have any access modifier
non-nested types can be public or internal
Semantics
C# nested types are implicitly static
C# does not have Java inner classes
C# does not have Java local classes
C# does not have Java anonymous classes
Delegates
delegate Type
a delegate is the last C# type...
declares a named signature including return type
like a C++ function pointer/object
similar to a Delphi closure
static Method
a delegate instance...
can hold and call a static method
Instance Method
a delegate instance...
can hold and call an instance method
Remember This?
Finally
Mulitcast delegate
a void return type delegate...
can hold multiple callback in its invocation list
first in, first called
delegate Notes
delegates
are called directly from invokers thread
can be compared for equality
can be ref and out parameters
are implicitly sealed types
combinable delegate
void return type
implicitly derive from System.Delegate
non-combinable delegate
non void return type
no out parameters
implicitly derive from System.MultiCastDelegate
Events
event Delegates
a delegate field can be marked as an event
only += and -= can be performed on the field
used widely in GUI classes
Event Delegates
.NET framework has many event delegates
by convention first parameter is event sender
and second parameter derives from EventArgs
Event Example
easy to imagine this in Java...
using an anonymous class
Event Properties
event fields can be exposed as properties
consider a class with lots of events
lazy creation might be useful
+= forwards to add
-= forwards to remove
Namespaces
namespace
a namespace is a logical naming mechanism
no relation to directory names or assemblies
a single .cs file can declare several namespaces
implicitly public
handy shorthand
no anonymous namespace
using Directive
only allowed at the start of namespace
respect scope, not recursive, no clash if no use
never affect other using directives
using Alias
a using alias creates alias for...
a namespace, or
a type
Namespace Notes
using
only at start of namespace
respects scope
never affect subsequent using directives
never affect subsequent using aliases
namespace
top level, non nested classes
public or internal, default to internal
cannot be protected or private
Assemblies
Modules
a physical .NET .DLL
contains types and MSIL code
unit of dynamic download
a PE (portable executable) file written using
C#, VB.NET, managed C++, raw MSIL, others...
but not a mixture
Assembly
a logical .NET .DLL containing...
manifest containing metadata
name, version#, file-list
referenced assemblies
type-list à containing module
security permissions
one or more modules containing types
one containing assembly entry point
zero or more resources
bitmaps, icons, etc
Deployment
to deploy an assembly...
drop it and its linked files into a single directory
goodbye registry
private assemblies...
live in their application's directory
are not versioned
shared assemblies...
live in a shared directory (Global Assembly Cache)
are versioned
need a shared name (aka strong name)
textual name
public key
digital signature
Versioning
assemblies with different versions co-exist
allows assembly evolution management
never modify an existing assembly
instead, create a new assembly with a new version
Version Policy
update policy controlled via .XML text file
default
major.minor as built
specific
major.minor as specified
QFE
latest build.revision?
safe
exactly as built
internal access
logical access control
public, protected, private
physical access control
internal access is within assembly
[Attributes]
What Are They?
attributes allow code elements to...
be tagged with declarative information
which is then added to the metadata
which can queried using reflection
for example...
suppose you wanted to record which developers implemented which types
...
create a class to represent the developer info
tag types with the developer attribute
specify developer attribute is only for types
decide whether to allow multiple tags
Attribute Class
create attribute class
must derive from System.Attribute
recommedation – use Attribute suffix in name
[ tag ]
tag code elements with [attribute]'s
ConstInt struct is tagged [ DeveloperAttribute ]
Problem
how can you specify which kind of code elements the attribute is to be used with?
Assembly, Module
Interface, Class, Struct, Enum, Delegate
Constructor, Method, Property, Field, Event
Parameter, ReturnValue
All
AttributeUsage
use a predefined AttributeUsage attribute!
with AttributeTarget enum
Multiple Tags
decide whether to allow multiple tags
use named parameter, AllowMultiple = true
Positional
positional parameters
must be specified in the attribution
correspond to constructor arguments
Named
named parameters
optionally specified in the attribution
must correspond to fields/properties
(non-static, public, read-write)
metadata
attributes are added to assembly metadata
visible though ILDASM or reflection
Notes
attributes are checked at compile time
incorrect usage causes compile time error
predefined attribute classes include
[Conditional]
[Obsolete]
[CLSCompliant]
[Serializable]
attribute parameter types limited to
bool, byte, char, double, float, int, long, short
string, object
public enums
Type
CLS attribute based templates
check out www.newtelligence.com
Reflection
Terminology
.NET has almost perfect reflection
reflection API's even allow dynamic creation
Attributes
retrieving custom attributes
Remember This?
Finally
Summary
arrays: rectangular, ragged, params
string: immutable, readonly[], verbatim
class: ref/out, static c'tor, boxing
exceptions: lock, no throw-specs
GC: d'tor, using statement, IDisposable
inheritance: positional, virtual/override
interfaces: no fields, EII, properties, indexers
nested types: Java access, C++ semantics
delegates: function pointers, single and multicast
events: restricted multicast delegate
assemblies: logical DLL, no registry, versioning
namespaces: shorthand syntax
reflection: metadata, introspection, intercession
attributes: add to metadata, reflect
Standards
ECMA/TC39/2000-2
Standard 1, C#
Standard 2, Common Language Infrastructure
Timeline
March 2001 – draft submission
Sept 2001 – final submission
Dec 2001 – Version 1 adopted by GA
Jan 2002 – submit to ISO for fast track process
Bibliography
Presenting C#
Christophe Wille; SAMS
A Programmer's Introduction to C#
Eric Gunnerson; Apress
Programming C# with the public Beta
Harvey, Robinson,Templeman, Watson; Wrox
C# Essentials
Albahari, Drayton, Merrill; O'Reilly
Inside C#
Tom Archer; MS Press