|
|
|
|
|
|
|
string |
|
class |
|
constructors |
|
fields |
|
parameters |
|
arrays |
|
boxing |
|
exceptions |
|
garbage collection |
|
inheritance, interfaces, abstract classes |
|
nested types |
|
delegates and events |
|
namespaces |
|
assemblies |
|
attributes |
|
reflection |
|
|
|
|
|
|
|
string is a reference type |
|
the only one with a literal syntax |
|
immutable; just like in Java |
|
|
|
|
|
string has a readonly indexer |
|
integer index is always bounds checked |
|
throws ArgumentOutOfRangeException |
|
|
|
|
string is an alias for System.String |
|
|
|
|
System.Text.StringBuilder |
|
|
|
|
|
usual syntax |
|
embedded escape chars, but no octal |
|
unusual syntax |
|
@ verbatim string literals |
|
|
|
|
|
equality operators are overloaded |
|
they compare the values not the references |
|
relational operators are not overloaded |
|
binary + is overloaded, forwards to .Concat |
|
operator += too |
|
|
|
|
|
|
a user-defined reference type |
|
|
|
|
|
a class local variable lives on the stack |
|
is not definitely assigned |
|
can be initialised with null or a c'tor call |
|
|
|
|
|
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 |
|
|
|
|
|
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... |
|
are default initialised by default in all c'tors |
|
can be initialised in variable initialiser |
|
can be explicitly initialised in a c'tor |
|
|
|
|
|
readonly instance fields... |
|
are instance fields that cannot be assigned to |
|
|
|
|
|
|
|
const fields are implicitly static |
|
only simple types, enums, & string can be const |
|
const fields require a variable initializer |
|
|
|
|
|
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 |
|
|
|
|
|
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 |
|
|
|
|
|
a plain parameter is a copy of the argument |
|
no frills bitwise copy |
|
the argument must be definitely assigned |
|
argument can be an "rvalue" |
|
|
|
|
|
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 |
|
|
|
|
|
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 |
|
|
|
|
|
readonly, const, and in, are all C# keywords |
|
they cannot be applied to parameters |
|
reference types always grant write access |
|
|
|
|
|
|
|
C# supports rectangular arrays |
|
rectangular arrays are reference types |
|
|
|
|
|
array instances are created using new |
|
rectangular arrays must specify all dimensions |
|
array instance elements are default initialised |
|
|
|
|
|
arrays can be initialised |
|
omitted initialisers are not permitted |
|
array size may be omitted |
|
standard shortcut notation |
|
|
|
|
all array types inherit from System.Array |
|
|
|
|
|
all array access is bounds checked |
|
throws IndexOutOfRangeException |
|
|
|
|
|
|
|
C# also supports ragged arrays |
|
arrays of arrays |
|
array instance still created using new |
|
|
|
|
|
each sub array can be intialised as before |
|
you can only specify the first dimension |
|
|
|
|
|
C# supports variadic functions |
|
params keyword can be used on array parameter |
|
only on a single dimension array parameter |
|
|
|
|
|
params with object as the element type |
|
creates a truly variadic function |
|
thanks to boxing |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
everything implicitly inherits from object |
|
arrays, classes, interfaces, delegates |
|
structs, enums, as well! |
|
|
|
|
|
a reference can bind to a value |
|
does the reference refer into the stack? |
|
if so what happes when the scope ends? |
|
|
|
|
|
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 copies the boxed value back again |
|
this requires an explicit cast to exact type |
|
if the target type is wrong -
InvalidCastException |
|
|
|
|
object is an alias for System.Object |
|
|
|
|
|
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 |
|
|
|
|
|
|
|
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 * |
|
|
|
|
|
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) |
|
|
|
|
|
two restrictions |
|
a private method cannot be virtual |
|
a struct can't declare a protected member |
|
|
|
|
|
a virtual method... |
|
introduces a method implementation |
|
cannot be declared in a struct |
|
|
|
|
|
an override method... |
|
specialises an inherited identical virtual
method |
|
is implicitly virtual itself |
|
cannot be declared in a struct * |
|
|
|
|
|
a sealed override method... |
|
specialises an inherited identical virtual
method |
|
which cannot itself be overriden |
|
cannot be declared in a struct |
|
|
|
|
|
a new method... |
|
hides an identical inherited method |
|
can be used in combination with virtual |
|
cannot be used in combination with override |
|
|
|
|
|
|
|
|
|
interfaces contain method signatures |
|
no access modifier, implicitly public |
|
no fields, not even static ones |
|
|
|
|
|
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 |
|
|
|
|
|
"implicit" interface implementation |
|
methods must be explicitly declared public |
|
by default methods are not virtual |
|
|
|
|
|
explicit interface implementation |
|
cannot have access modifier (private-ish) |
|
cannot be virtual |
|
|
|
|
|
an interface can declare a property |
|
readwrite, readonly, writeonly |
|
|
|
|
|
an interface can declare an indexer |
|
readwrite, readonly, writeonly |
|
indexers are not static operators |
|
|
|
|
|
use is operator to check for type support |
|
returns true or false |
|
a cast can throw an InvalidCastException |
|
|
|
|
|
the as operator is similar |
|
performs the conversion if the type is supported |
|
returns null if its not |
|
|
|
|
|
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 |
|
|
|
|
|
interface parameters |
|
can be ref qualified |
|
can be out qualified |
|
|
|
|
|
|
|
|
|
an abstract class... |
|
cannot be instantiated |
|
can extend an abstract class or a class |
|
otherwise the same as a class |
|
|
|
|
|
an abstract method... |
|
can only be declared in an abstract class |
|
has no body |
|
cannot be private |
|
|
|
|
|
an abstract method... |
|
can override a inherited virtual method |
|
must be implemented with the same access |
|
|
|
|
|
a sealed class |
|
cannot be derived from |
|
cannot declare virtual methods |
|
cannot declare abstract methods |
|
structs and enums are implicitly sealed |
|
|
|
|
|
|
method modifier combinations |
|
|
|
|
|
|
the root of all Exception clasases |
|
|
|
|
|
|
|
you can throw any object you like |
|
as long as it's derived from System.Exception |
|
|
|
|
|
you can separate out error handling code |
|
in a catch { block } after a try { block } |
|
goodbye HRESULT |
|
|
|
|
|
you can ensure code always runs |
|
in a finally { block } |
|
exception in finally block dominates |
|
you cannot jump out of a finally block |
|
|
|
|
|
deterministic finalisation via finally... |
|
is exception safe, but... |
|
is repetitive and doesn't scale |
|
is complex and fails to abstract |
|
|
|
|
|
after discussions on the .NET reflector |
|
M'Soft provided a solution consisting of... |
|
the IDisposable interface in combination with... |
|
the using statement |
|
|
|
|
|
|
|
|
|
C# does not have a synchronize keyword |
|
it has lock statements |
|
|
|
|
throw specifications - NO |
|
checked/unchecked distinction - NO |
|
compile time exceptions - NO |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
garbage collector finalizes objects |
|
when they become unreachable |
|
by calling Finalize( ) |
|
but you cannot override Object.Finalize!! |
|
or call it |
|
|
|
|
|
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 |
|
|
|
|
|
|
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 :-( |
|
|
|
|
|
|
|
|
|
|
|
a class or struct can declare nested types |
|
nested types default to private access |
|
non-nested types default to internal access |
|
|
|
|
|
a nested type... |
|
has access to all members of outer types |
|
but not vice versa |
|
C# follows Java access model |
|
|
|
|
|
there are five kinds of access |
|
nested types can have any access modifier |
|
non-nested types can be public or internal |
|
|
|
|
|
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 |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
a delegate instance... |
|
can hold and call a static method |
|
|
|
|
|
a delegate instance... |
|
can hold and call an instance method |
|
|
|
|
|
|
|
|
|
a void return type delegate... |
|
can hold multiple callback in its invocation
list |
|
first in, first called |
|
|
|
|
|
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 |
|
|
|
|
|
|
|
a delegate field can be marked as an event |
|
only += and -= can be performed on the field |
|
used widely in GUI classes |
|
|
|
|
|
.NET framework has many event delegates |
|
by convention first parameter is event sender |
|
and second parameter derives from EventArgs |
|
|
|
|
|
easy to imagine this in Java... |
|
using an anonymous class |
|
|
|
|
|
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 |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
only allowed at the start of namespace |
|
respect scope, not recursive, no clash if no use |
|
never affect other using directives |
|
|
|
|
|
a using alias creates alias for... |
|
a namespace, or |
|
a type |
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
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 |
|
|
|
|
|
|
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 |
|
|
|
|
|
assemblies with different versions co-exist |
|
allows assembly evolution management |
|
never modify an existing assembly |
|
instead, create a new assembly with a new
version |
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
logical access control |
|
public, protected, private |
|
physical access control |
|
internal access is within assembly |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
create attribute class |
|
must derive from System.Attribute |
|
recommedation – use Attribute suffix in name |
|
|
|
|
|
|
|
|
|
tag code elements with [attribute]'s |
|
ConstInt struct is tagged [ DeveloperAttribute ] |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
use a predefined AttributeUsage attribute! |
|
with AttributeTarget enum |
|
|
|
|
|
decide whether to allow multiple tags |
|
use named parameter, AllowMultiple = true |
|
|
|
|
|
positional parameters |
|
must be specified in the attribution |
|
correspond to constructor arguments |
|
|
|
|
|
|
named parameters |
|
optionally specified in the attribution |
|
must correspond to fields/properties |
|
(non-static, public, read-write) |
|
|
|
|
|
attributes are added to assembly metadata |
|
visible though ILDASM or reflection |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
.NET has almost perfect reflection |
|
reflection API's even allow dynamic creation |
|
|
|
|
retrieving custom attributes |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
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 |
|
|
|
|
|
|
|
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 |
|