By Joseph Albahari, Ben Albahari
Book Price: $14.99 USD
£8.99 GBP
PDF Price: $11.99
Cover | Table of Contents
Func<int,int> sqr = x => x * x;
Console.WriteLine (sqr(3)); // 9 string[] names = { "Tom", "Dick", "Harry" };
// Include only names of >= 4 characters:
IEnumerable<string> filteredNames =
Enumerable.Where (names, n => n.Length >= 4); IEnumerable<string> filteredNames =
names.Where (n => n.Length >= 4); Func<int,int> sqr = x => x * x;
Console.WriteLine (sqr(3)); // 9 string[] names = { "Tom", "Dick", "Harry" };
// Include only names of >= 4 characters:
IEnumerable<string> filteredNames =
Enumerable.Where (names, n => n.Length >= 4); IEnumerable<string> filteredNames =
names.Where (n => n.Length >= 4);filteredNames, we can further simplify our
query: var filteredNames = names.Where (n => n.Length == 4); using System; // importing namespace
class Test // class declaration
{
static void Main( ) // method declaration
{
int x = 12 * 30; // statement 1
Console.WriteLine (x); // statement 2
} // end of method
} // end of classint x = 12 * 30; Console.WriteLine (x);
x, which
is an integer type. The second statement calls the Console class's WriteLine method to print the variable
x to a text window on the
screen.Main: static void Main( )
{
...
} using System;
class Test
{
static void Main( )
{
Console.WriteLine (FeetToInches (30)); // 360
Console.WriteLine (FeetToInches (100)); // 1200
}
static int FeetToInches (int feet)
{
int inches = feet * 12;
return inches;
}
}FeetToInches that has a parameter for
inputting feet, and a return type for outputting inches:static int InchesToFeet (int feet) {...}
30 and 100
are the arguments passed to the FeetToInches method. The using System;
class Test
{
static void Main( )
{
int x = 12 * 30;
Console.WriteLine (x);
}
}System Test Main x Console WriteLine
myVariable), and all other identifiers
should be in Pascal case (e.g., MyMethod).using class static void int
abstract | enum | long | stackalloc |
|---|---|---|---|
as | event | namespace | static |
base | explicit | new | string |
bool | extern | null | struct |
break | false | object | switch |
byte | finally | operator | this |
case | fixed | out | throw |
catch | float | override | true |
char | for | params | try |
checked | foreach | private | typeof |
class | goto | protected | uint |
const | if | public | ulong |
continue | implicit | readonly | unchecked |
decimal | in | ref | unsafe |
default | int | return | ushort |
delegate | interface | sbyte | using |
do | internal | sealed | virtual |
double | is | short | void |
else | lock | sizeof | while |
class class {...} // illegal
class @class {...} // legal@myVariable is the same as
myVariable.add | get | let | set |
ascending | global | on | value |
by | group | orderby | var |
descending | in | partial | where |
equals | into | remove |
x in our first program: static void Main( )
{
int x = 12 * 30;
Console.WriteLine (x);
}x is int.int type is a predefined primitive
type for representing the set of integers that fits into 32 bits of
memory, from –231 to
231–1. We can perform functions such as
arithmetic with instances of the int type, as follows:int x = 12 * 30;
string type. The string type represents a sequence of
characters, such as ".NET" or http://oreilly.com. We can manipulate strings by
calling functions on them as follows:string message = "Hello world"; string upperMessage = message.ToUpper( ); Console.WriteLine (upperMessage); // HELLO WORLD int x = 2007; message = message + x.ToString( ); Console.WriteLine (message); // Hello world2007
bool type has
exactly two possible values: true
and false. The bool type is commonly used to conditionally
branch execution flow based with an if statement. For example: bool simpleVar = false;
if (simpleVar)
Console.WriteLine ("This will not print");
int x = 5000;
bool lessThanAMile = x < 5280;
if (lessThanAMile)
Console.WriteLine ("This will print");System namespace in
the .NET Framework contains many important types that C# does not
predefine (e.g., DateTime).C# type | System type | Suffix | Size | Range |
|---|---|---|---|---|
Integral—signed | ||||
sbyte | SByte | 8
bits | –27 to
27–1 | |
short | Int16 | 16
bits | –215 to
215–1 | |
int | Int32 | 32
bits | –231 to
231–1 | |
long | Int64 | L | 64
bits | –263 to
263–1 |
Integral—unsigned | ||||
byte | Byte | 8
bits | 0 to
28–1 | |
ushort | UInt16 | 16
bits | 0 to
216–1 | |
uint | UInt32 | U | 32
bits | 0 to
232–1 |
ulong | UInt64 | UL | 64
bits | 0 to
264–1 |
Real | ||||
float | Single | F | 32
bits | ±(
~10–45 to
1038) |
double | Double | D | 64
bits | ±(
~10–324 to
10308) |
decimal | Decimal | M | 128
bits | ±(
~10–28 to
1028) |
int and long are first-class citizens and C# and the
runtime favor both. The other integral types are typically used for
interoperability or when space efficiency is paramount.float and double are called floating-point
types and are typically used for scientific calculations. The
decimal type is typically used for
financial calculations, where base-10-accurate arithmetic and high
precision are required.0x; prefix. For example:int x = 127; long y = 0x7F;
double d = 1.5; double million = 1E06;
double or an
integral type:E), it is a double.int, uint, ulong, and long.Console.Write( 1.0.GetType( )); // Double (double) Console.Write( 1E06.GetType( )); // Double (double) Console.Write( 1.GetType( )); // Int32 (int) Console.Write(0xF0000000.GetType( )); // UInt32 (uint)
bool type (aliasing the
System.Boolean type) is a logical
value that can be assigned the literal true or false.BitArray class in the
System.Collections namespace, which
is designed to use just one bit per Boolean value.bool value. Value types typically have a
very simple notion of equality:int x = 1, y = 2, z = 1; Console.WriteLine (x == y); // False Console.WriteLine (x == z); // True
public class Dude
{
public string Name;
public Dude (string n) { Name = n; }
}
Dude d1 = new Dude ("John");
Dude d2 = new Dude ("John");
Console.WriteLine (d1 == d2); // False
Dude d3 = d1;
Console.WriteLine (d1 == d3); // Trueenum type members, by comparing their
underlying integral values.Use Umbrella method returns true if it's rainy or sunny (to protect us
from the rain or the sun), as long as it's not also windy (as
umbrellas are useless in the wind): static bool UseUmbrella (bool rainy, bool sunny,
bool windy)
{
return ! windy && (rainy || sunny);
}char type (aliasing the
System.Char type) represents a
Unicode character, and it occupies two bytes. A char literal is specified inside single quotes:char c = 'A'; // simple character
char newLine = '\n'; char backSlash = '\\';
Char | Meaning | Value |
|---|---|---|
\' | Single quote | 0x0027 |
\" | Double quote | 0x0022 |
\\ | Backslash | 0x005C |
\0 | Null | 0x0000 |
\a | Alert | 0x0007 |
\b | Backspace | 0x0008 |
\f | Form feed | 0x000C |
\n | New line | 0x000A |
\r | Carriage return | 0x000D |
\t | Horizontal tab | 0x0009 |
\v | Vertical tab | 0x000B |
\u (or \x) escape sequence lets you specify any Unicode character via
its four-digit hexadecimal code:char copyrightSymbol = '\u00A9'; char omegaSymbol = '\u03A9'; char newLine = '\u000A';
char to a numeric type works for the
numeric types that can accommodate an unsigned short.
For other numeric types, an explicit conversion is required.System.String type) represents an immutable
sequence of Unicode characters. A string literal is specified inside
double quotes:string a = "Heat";
string is a reference type, not a value type. Its equality
operators, however, implement value-type semantics.char literals also work inside strings:string a = "Here's a tab:\t";
string a1 = "\\\\server\\fileshare\\helloworld.cs";
string literals. A verbatim
string literal is prefixed with @
and does not support escape sequences. The following verbatim string
is identical to the preceding one:string a2 = @"\\server\fileshare\helloworld.cs";
string escaped = "First Line\r\nSecond Line"; string verbatim = @"First Line Second Line"; Console.WriteLine (escaped == verbatim); // True
char[] vowels = new char[5]; // Declare an array of 5 characters
vowels [0] = 'a'; vowels [1] = 'e'; vowels [2] = 'i'; vowels [3] = 'o'; vowels [4] = 'u'; Console.WriteLine (vowels [1]); // e
for loop statement to iterate through
each element in the array. The for
loop in this example cycles the integer i from 0 to
4:for (int i = 0; i < vowels.Length; i++) Console.Write (vowels [i]); // aeiou
IEnumerable<T>, so you can enumerate
members with the foreach
statement:foreach (char c in vowels) Console.Write (c); // aeiou
Length property of an array
returns the number of elements in the array. Once an array has been
created, its length cannot be changed. The System.Collection namespace and subnamespaces
provide higher-level data structures, such as dynamically sized arrays
and dictionaries. char[] vowels = new char[] {'a','e','i','o','u'};System.Array class, which defines common
methods and properties for all arrays. This includes instance properties such as Length and Rank, and static methods to:CreateInstance)GetValue/SetValue)BinarySearch) or an unsorted array (IndexOf, LastIndexOf, Find, FindIndex,
FindLastIndex)Sort)Copy) static int Factorial (int x)
{
if (x == 0) return 1;
return x * Factorial (x-1);
}int is allocated on the stack, and each
time the method exits, the int is
deallocated.StringBuilder object is created on the
heap, while the sb
reference is created on the stack: static void Test()
{
StringBuilder sb = new StringBuilder();
Console.WriteLine (sb.Length);
}Test method
finishes, sb pops off the stack,
and the StringBuilder object is
no longer referenced, so it becomes eligible for garbage
collection.12
12 and 30), as follows:12 * 30
(12*30) in the following example:1 + (12 * 30)
Math.Log (1)
Console.WriteLine (1)
1 + Console.WriteLine(1) // Compile-time error
x = x * 5
x and 10 to y:y = 5 * (x = 2)
a = b = c = d = 0
string someWord = "rosebud"; int someNumber = 42; bool rich = true, famous = false;
const double c = 2.99792458E08; c+=10; // error
static void Main()
{
int x;
{
int y;
int x; // Error, x already defined
}
{
int y; // OK, y not in scope
}
Console.WriteLine(y); // Error, y is out of scope
}// Declare variables with declaration statements: string s; int x, y; System.Text.StringBuilder sb; // Expression statements x = 1 + 2; // Assignment expression x++; // Increment expression y = Math.Max (x, 5); // Assignment expression Console.WriteLine (y); // Method call expression sb = new StringBuilder( ); // Assignment expression new StringBuilder( ); // Object instantiation // expression
RSA type,
which handles public key encryption, is defined within the following
namespace:System.Security.Cryptography
RSA's Create method:System.Security.Cryptography.RSA rsa = System.Security.Cryptography.RSA.Create( );
public, internal,
private, and so on.namespace keyword defines a
type within a namespace. For example: namespace Outer.Middle.Inner
{
class Class1 {}
class Class2 {}
} namespace Outer
{
namespace Middle
{
namespace Inner
{
class Class1 {}
class Class2 {}
}
}
}Class1 in the preceding example as Outer.Middle.Inner.Class1.Outer in our example.using directive
imports a namespace. This is a convenient way to
refer to types without their fully qualified names. For
example: using Outer.Middle.Inner;
class Test // Test is in the global namespace
{
static void Main( )
{
Class1 c; // Don't need fully qualified name
}
}using directive can be
nested within a namespace itself to limit the scope of the directive. class YourClassName
{
}preceding the keyword class | attributes and class modifiers. The non-nested
class modifiers are public, internal,
abstract, sealed, static, unsafe, and partial |
following YourClassName | generic type parameters, a base class, and
interfaces |
within the braces | class members (these are methods, properties,
indexers, events, fields, constructors, operator functions, nested
types, and a finalizer) |
class Octopus
{
string name;
public int Age = 10;
}readonly
modifier to prevent it from being modified after construction. A
read-only field can be assigned only in its declaration or within the
enclosing type's constructor.0, \0, null,
false). Field initializers run before constructors:string name = "anonymous";
static readonly int legs = 8, eyes = 1;
void return type,
indicating that it doesn't return any value to its caller. A method
can also output data back to the caller via ref/out parameters.Asset: public class Asset
{
public string Name;
}Stock and House, which will inherit from Asset. Stock and House get everything an Asset has, plus any additional members that
they define:public class Stock : Asset // inherits from Asset { public long SharesOwned; } public class House : Asset // inherits from Asset { public decimal Mortgage; }
Stock msft = new Stock { Name="MSFT",
SharesOwned=1000 };
Console.WriteLine (msft.Name); // MSFT
Console.WriteLine (msft.SharesOwned); // 1000
House mansion = new House { Name="Mansion",
Mortgage=250000 };
Console.WriteLine (mansion.Name); // Mansion
Console.WriteLine (mansion.Mortgage); // 250000Stock and House inherit the Name property from the base
class Asset. public static void Display (Asset asset)
{
System.Console.WriteLine (asset.Name);
}Stock and a House because they are both Assets:Stock msft = new Stock ... ; House mansion = new House ... ; Display (msft); Display (mansion);
Stock and House) have all the features of their base
class (Asset). The converse,
however, is not true. If Display
was modified to accept a House, you
could not pass in an Asset.object (System.Object) is the
ultimate base class for all types. Any type can be upcast to object. public class Stack
{
int position;
object[] data = new object[10];
public void Push (object obj)
{ data[position++] = obj; }
public object Pop()
{ return data[--position]; }
}Stack works with the
object type, we can Push and Pop instances of any type
to and from the Stack: Stack stack = new Stack();
stack.Push ("sausage");
// Explicit cast is needed because we're downcasting:
string s = (string) stack.Pop();
Console.WriteLine (s); // sausageobject is a reference type, by
virtue of being a class. Despite this, value types, such as int, can also be cast to and from object, and so be added to our stack. This
feature of C# is called type unification:stack.Push (3); int three = (int) stack.Pop();
object, the CLR must perform some special work
to bridge the difference in semantics between value and reference types.
This process is called boxing and
unboxing.object class, or an
interface (which we will visit later). In this example, we
box an int
into an object:int x = 9; object obj = x; // box the int
int y = (int)obj; // unbox the int
InvalidCastException if the
check fails. For instance, the following throws an exception because
object). public struct Point
{
int x, y;
public Point (int x, int y) {this.x = x; this.y = y;}
}
...
Point p1 = new Point (); // p1.x and p1.y will be 0
Point p2 = new Point (1, 1); // p1.x and p1.y will be 1 public struct Point
{
int x = 1; // Illegal, cannot initialize field
int y;
public Point() {} // Illegal, cannot have
// parameterless constructor
public Point(int x) {this.x = x;} // illegal, must
// assign field y
}struct to class makes this example legal.publicinternalprivateprotectedprotected internalprotected and internal accessibility. (This is
less restrictive than protected or internal alone.)Class2 is accessible from
outside its assembly; Class1 is
not: class Class1 { } // Class1 is internal (default)
public class Class2 { }ClassB exposes field x to other types in the same assembly;
ClassA does not: class ClassA { int x; } // x is private
// (default)
class ClassB { internal int x; }Subclass can
call Bar but not Foo: class BaseClass
{
void Foo() { } // Foo is private (default)
protected void Bar() { }
}
class Subclass : BaseClass
{
void Test1() { Foo(); } // Error: cannot access Foo
void Test2() { Bar(); } // OK
}internal type with public members. For example: class C { public void Foo() {} }internal
accessibility caps Foo's
accessibility, effectively making Foo
internal. The reason Foo
would be marked public is to make
for easier refactoring, should C
later be changed to public.