97041
97041
97041
https://ebookultra.com
https://ebookultra.com/download/c-precisely-
second-edition-peter-sestoft/
https://ebookultra.com/download/c-in-a-nutshell-1st-edition-peter-
prinz/
ebookultra.com
https://ebookultra.com/download/c-in-a-nutshell-1st-edition-peter-
drayton/
ebookultra.com
https://ebookultra.com/download/rabies-second-edition-alan-c-jackson/
ebookultra.com
https://ebookultra.com/download/evaluating-contract-claims-second-
edition-r-peter-davison/
ebookultra.com
A New Land Law Second Edition Peter Sparkes
https://ebookultra.com/download/a-new-land-law-second-edition-peter-
sparkes/
ebookultra.com
https://ebookultra.com/download/mathematical-techniques-in-gis-second-
edition-peter-dale/
ebookultra.com
https://ebookultra.com/download/analysis-of-longitudinal-data-second-
edition-peter-diggle/
ebookultra.com
https://ebookultra.com/download/survival-math-for-marketers-1st-
edition-peter-c-weiglin/
ebookultra.com
https://ebookultra.com/download/psycho-oncology-second-edition-jimmie-
c-holland/
ebookultra.com
C Precisely Second Edition Peter Sestoft Digital Instant
Download
Author(s): Peter Sestoft, Henrik I. Hansen
ISBN(s): 9780262516860, 0262516861
Edition: second edition
File Details: PDF, 6.64 MB
Year: 2011
Language: english
public static IEnumerable<R> Scan<A,R>(this IEnumerable<A> xs, Func<R,A,R> f, R e)
{ public static IEnumerable<R> Scan<A,R>(this IEnumerable<A> xs, Func<R,A,R> f, R e)
yield return e; {
public static IEnumerable<R> Scan<A,R>(this IEnumerable<A> xs, Func<R,A,R> f, R e)
yield return e;
foreach (var x in xs) { foreach (var x in xs) {{ yield return e;
foreach (var x in xs) {
e = f(e, x); e = f(e, x); e = f(e, x);
yield return e; yield return e;
yield return e; } }
} }
}
}
}
C# Precisely
Second Edition
Peter Sestoft
Henrik I. Hansen
C# Precisely
Second Edition
All rights reserved. No part of this book may be reproduced in any form by any electronic or mechanical
means (including photocopying, recording, or information storage and retrieval) without permission in
writing from the publisher.
Sestoft, Peter.
C# precisely / Peter Sestoft and Henrik I. Hansen. — 2nd ed.
p. cm.
Includes bibliographic references and index.
ISBN 978-0-262-51686-0 (pbk.: alk. paper)
1. C# (Computer program language) I. Hansen, Henrik I. II. Title.
QA76.73.C154S47 2012
005.133—dc23 2011021052
10 9 8 7 6 5 4 3 2 1
Contents ix
29 Namespaces 210
29.1 The using Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
32 Attributes 216
32.1 Some Predefined Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
32.2 Declaring and Using Custom Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . 216
34 Resources 220
Index 221
Contents
Preface xi
3 C# Naming Conventions 4
7 Strings 18
7.1 String Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7.2 String Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
8 String Builders 26
9 Arrays 28
9.1 One-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
9.2 Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
9.3 Class Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
10 Classes 34
10.1 Class Declarations and Class Bodies . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
10.2 Class Modifiers abstract, sealed, static . . . . . . . . . . . . . . . . . . . . . . . 36
10.3 Member Access Modifiers private, protected, internal, public . . . . . . . . . . 36
10.4 Subclass, Base Class, Inheritance, and Hiding . . . . . . . . . . . . . . . . . . . . . . . 38
10.5 Field Declarations in Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
10.6 Constant Declarations in Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
10.7 Method Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
vi Contents
12 Expressions 60
12.1 Table of Expression Forms and Predefined Operators . . . . . . . . . . . . . . . . . . . 60
12.2 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
12.3 The checked and unchecked Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 62
12.4 Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
12.5 Bitwise Operators and Shift Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
12.6 Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
12.7 Assignment Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
12.8 Conditional Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
12.9 Object Creation Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
12.10 Object Initializer (C# 3.0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
12.11 Collection Initializers (C# 3.0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
12.12 Struct Value Creation Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
12.13 Instance Test Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
12.14 Instance Test and Cast Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
12.15 Field Access Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
12.16 The Current Object Reference this . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
12.17 Method Call Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
12.18 Property Access Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
12.19 Indexer Access Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
12.20 Type Cast Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
12.21 The typeof Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
12.22 Anonymous Method Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
12.23 Lambda Expressions (C# 3.0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
12.24 Anonymous Object Expressions (C# 3.0) . . . . . . . . . . . . . . . . . . . . . . . . . 92
12.25 Implicitly Typed Array Creation Expressions (C# 3.0) . . . . . . . . . . . . . . . . . . 92
Contents vii
13 Statements 94
13.1 Expression Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
13.2 Block Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
13.3 The Empty Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
13.4 Declaration Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
13.5 Choice Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
13.6 Loop Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
13.7 Returns, Labeled Statements, Exits, and Jumps . . . . . . . . . . . . . . . . . . . . . . 102
13.8 Throwing and Catching Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
13.9 The checked and unchecked Statements . . . . . . . . . . . . . . . . . . . . . . . . . 108
13.10 The using Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
13.11 The lock Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
13.12 The yield Statement and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
15 Interfaces 116
15.1 Interface Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
15.2 Classes and Struct Types Implementing Interfaces . . . . . . . . . . . . . . . . . . . . 118
15.3 Explicit Interface Member Implementations . . . . . . . . . . . . . . . . . . . . . . . . 118
20 Exceptions 128
xi
Notational Conventions
Symbol Meaning
a expression or value of array type
b expression or value of boolean type
C class
D delegate type
e expression
E exception type or event name
f field
g group of items (Linq)
i expression or value of integer type
I interface type
M method
N namespace
o expression or value of object type
P property name
s expression of type string
S struct type
sig signature of method or constructor
t type name or type expression (simple type or value type or reference type)
T, U type parameters (generic types and methods)
u expression or value of thread type
v value of any type
x, y variable or parameter or field or array element or range variable (Linq)
xs, ys stream of items, such as an enumerable (Linq)
In this book, fragments of the C# grammar are presented using an informal notation, with non-terminal
symbols such as class-declaration in italics, terminal symbols such as class in typewriter font, and
metavariables such as C for class names and M for method names.
A complete and detailed grammar for C# can be found in the official language specification (see
section 34). The complete grammar is not included here because it runs to more than 30 dense pages and
yet is too general: many well-formedness requirements must be expressed as additional side conditions
on the grammar.
xii
C# Precisely
2 Compiling, Loading, and Executing C# Programs
1.2 Execution
An executable file Prog.exe compiled from program Prog.cs can be (loaded and) executed by typing
its name on the command line or by explicitly invoking the run-time system. This will execute the static
method Main() or Main(String[] args) in Prog.cs, in the latter case binding the command line argu-
ments arg1, arg2, . . . to the array elements args[0], args[1], . . . (see examples 1 and 2).
The /main compiler option can be used to specify the entry point: the class whose Main method must
be executed after loading an executable.
Compiling, Loading, and Executing C# Programs 3
The resulting assembly consists of two files: the main file Prog.exe, and file Mod.netmodule which
contains the external module. The assembly has a manifest with version number, other metadata, and
references to two other assemblies: the library Lib, and mscorlib which is included by default.
3 C# Naming Conventions
The following naming conventions are often followed, although not enforced by the C# compiler:
• If a name is composed of several words, then each word (except possibly the first one) begins with
an uppercase letter. Examples: currentLayout, LayoutComponent.
• Names of local variables, parameters, and private or protected fields begin with a lowercase letter.
Examples: vehicle, currentVehicle. Avoid using lowercase letter l or uppercase letter O as
names.
• Names of public or internal instance fields, static fields, and named constants begin with an upper-
case letter. Examples: Vehicle, MaxValue.
• Names of classes, methods, events, properties, and enum types begin with an uppercase letter.
Examples: Cube, ColorCube.
• Names of interfaces begin with the letter I followed by an uppercase letter. Example: IEnumerable.
• A namespace name usually is a dot-separated sequence of names, each of which begins with an
uppercase letter (System or System.Text or System.Text.RegularExpressions), but could also
be a reverse domain name (dk.itu.c5 or ch.cern.mathlib).
LayoutExample(int j) {
this.j = j; // One-line body
}
Class Object is the base class (superclass) of all classes. Let o1 and o2 be expressions of type Object:
• o1.Equals(o2) returns true if o1 and o2 are equal; otherwise false. By default, values of reference
type are equal if created by the same execution of new; but (for example) class String overrides
Equals to compare the string contents instead (section 7), and class ValueType overrides Equals
so that two values of a struct type are equal if all their fields are equal.
• Object.ReferenceEquals(o1, o2) returns true if both o1 and o2 are null, or if both refer to the
same object or array or delegate; otherwise false. False also if any of o1 or o2 has value type.
• Object.Equals(o1, o2) returns true if Object.ReferenceEquals(o1, o2) or o1.Equals(o2)
does; otherwise false. This is inefficient for arguments of value type that get boxed and then com-
pared using o1’s Equals method.
• o1.GetType() returns the unique object of class Type that represents the run-time type of o1.
• o1.GetHashCode() returns a hash code for o1 as an int, useful when o1 is used as a key in a hash
table (section 27.7). Subclasses should override this method so that (1) if o1 and o2 are equal by
Equals, then they have the same hash code; (2) modifications to o1 do not change its hash code;
(3) the hash codes should be uniformly distributed; and (4) the method should be fast and must not
throw exceptions. All simple types and class String have appropriate GetHashCode methods.
• o1.ToString() returns a human-readable culture-sensitive representation of the object o1.
Class String is a frequently used subclass of Object and is a reference type (section 7).
Class Array is a subclass of Object and the base class of all array types such as int[] (section 9).
Class ValueType is a subclass of Object and the base class of all value types, including the simple types,
the struct types, and the enum types. It is not itself a value type. If v1 and v2 have a struct type (that
derives from ValueType) then v1.Equals(v2) uses reflection to compare the fields of v1 and v2 using
Equals. This can be slow, so struct types should override Equals. Also, struct types that have modifiable
fields should override GetHashCode; the default method may be unsuitable for such struct types.
Class Enum is a subclass of ValueType and the base class of all enum types (section 16) but is not itself
an enum type. It implements enum-specific methods inherited by all enum types.
Class Delegate is a subclass of Object and the base class of all delegate types (section 17) but is not itself
a delegate type. It implements delegate-specific methods inherited by all delegate types.
Data and Types 9
Class Object
...
Class String Class Array Class ValueType Class Delegate other classes
... ...
array types delegate types
Class Enum
5.3 Conversion
For a given type ts there may exist an implicit or explicit conversion of a value of type ts into a value of
another type tt. If there is an implicit conversion from type ts to type tt, then an expression of type ts
can be used wherever an expression of type tt is expected. In particular, any value v of type ts may be
bound to a variable or field or parameter x of type tt, for instance, by the assignment x = v.
If there is an explicit conversion from ts to tt, then a cast expression (section 12.20) can be used to
obtain a value of type tt from the value of type ts.
double d = 2.9;
Console.WriteLine((int)d); // ET double-->int; prints 2
Console.WriteLine((int)(-d)); // ET double-->int; prints -2
uint seconds = (uint)(24 * 60 * 60); // EB int-->uint
double avgSecPerYear = 365.25 * seconds; // I uint-->double
float f = seconds; // IL uint-->float
long nationalDebt1 = 14349539503882;
double perSecond = 45138.89;
decimal perDay = // ED double-->decimal
seconds * (decimal)perSecond; // I uint-->decimal
double nd2 = nationalDebt1 + (double)perDay; // ER decimal-->double
long nd3 = (long)nd2; // ET double-->long
float nd4 = (float)nd2; // ER double-->float
double
decimal
float
ulong
long
uint
int
ushort
short char
byte
sbyte
12 Data and Types
class Scope {
void M1(int x) { // Declaration of parameter x (#1); shadows x (#5)
x = 7; // x #1 in scope; legal, but no effect outside M1
} //
void M3() { //
int x; // Declaration of variable x (#2); shadows x (#5)
x = 7; // x #2 in scope
}
void M4() { //
x = 7; // x #5 in scope
// int x; // Would be ILLEGAL, giving a new meaning to x
}
void M5() { //
{ //
int x; // Declaration of variable x (#3); shadows x (#5)
x = 7; // x #3 in scope
} //
{ //
int x; // Declaration of variable x (#4); shadows x (#5)
x = 7; // x #4 in scope
} //
}
public int x; // Declaration of field x (#5)
}
int x, y, z;
if (args.Length == 0)
x = y = 10;
else
x = args.Length;
Console.WriteLine(x); // x definitely assigned, y and z not (#1)
y = x;
for (int i=0; i<y; i++) // x and y definitely assigned, z not (#2)
z = i;
// Console.WriteLine(z); // z still not definitely assigned! (#3)
16 Variables, Parameters, Fields, and Scope
The expression (section 12) must have a compile-time type and hence cannot be an anonymous method
(section 12.22), a lambda expression (section 12.23), or the null literal. The declared variable is given
the type inferred for the expression as if that type had been explicitly stated; subsequent uses of, or
assignments to, the variable do not affect this type inference process. The variable remains statically
typed as if the type had been explicitly given.
The var keyword may be used also in for statements (section 13.6.1), foreach statements (sec-
tion 13.6.2), and using statements (section 13.10). It cannot be used for declaration of fields, method
parameters, or method return types; their types must always be given explicitly. Since var is not a type
but a keyword that declares a variable using compile-time type inference, var also cannot be used in casts,
as array element type, as type parameter in generic types, and so on.
6.4 The Type dynamic: Run-Time Resolution of Calls and More (C# 4.0)
With type dynamic, one can obtain behavior very similar to that of dynamically typed programming
languages such as Clojure, Groovy, Javascript (Jscript), Python, Ruby, Scheme, and others.
If an expression has type dynamic, then a method call, operator application, delegate call, or field
access involving that expression will be resolved dynamically at run-time rather than at compile-time. This
means that almost any such expression will be accepted by the compiler but may fail with an exception at
run-time.
Whereas var is a keyword, dynamic is a type. Hence, unlike var, dynamic can be used for fields,
method parameters, and method return types as well as in constructed types such as dynamic[] and
List<dynamic>.
Run-time resolution of method calls, operator applications, delegate applications, and field accesses
produces exactly the same result as compile-time resolution would produce. In those cases where compile-
time resolution would fail (causing the compiler to reject the program), run-time resolution will instead
throw an exception (typically RuntimeBinderException) at run-time. Thus the run-time system repli-
cates the compiler’s resolution machinery for this purpose. Since compile-time operations are moved to
run-time, where they may be executed repeatedly, operations involving expressions of type dynamic are
slower than those resolved at compile-time; in extreme cases, up to ten times slower. Nevertheless, run-
time resolution is convenient when calling external dynamic applications such as Microsoft Excel or web
browsers.
The run-time resolution machinery is called the Dynamic Language Runtime but is actually a set of
libraries built on top of the ordinary .NET run-time system.
More information and more examples using type dynamic are found in sections 12.17.8 and 18.
Variables, Parameters, Fields, and Scope 17
Example 15 Compile-Time Resolution and Checking of Operators, Assignments, and Field Accesses
class Phone {
public readonly String name;
public readonly int phone;
public Phone(String name, int phone) { ... }
}
...
var d1 = 34; // Inferred type int
int i1 = d1 * 2; //
int i2 = (int)d1 * 2; // Cast (int)d1 succeeds at compile-time
// bool b1 = d1; // Rejected at compile-time
// d1 = true; // Rejected at compile-time
var p1 = new Phone("Kasper", 5170);
String s1 = p1.name; // Field access checked only at compile-time
// int n1 = p1.age; // Field access rejected at compile-time
var p2 = new { name = "Kasper", phone = 5170 };
String s2 = p2.name; // Field access checked only at compile-time
// int n2 = p2.age; // Field access rejected at compile-time
dynamic d1 = 34;
int i1 = d1 * 2; // OK: cast (int)(d1*2) at run-time
int i2 = (int)d1 * 2; // OK: cast (int)d1 at run-time
// bool b1 = d1; // Compiles OK; cast (bool)d1 throws at run-time
d1 = true; // OK
bool b2 = d1; // OK: cast (bool)d1 succeeds at run-time
dynamic p1 = new Phone("Kasper", 5170);
String s1 = p1.name; // Field access checked at run-time
// int n1 = p1.age; // Compiles OK; field access throws at run-time
dynamic p2 = new { name = "Kasper", phone = 5170 };
String s2 = p2.name; // Field access checked at run-time
// int n2 = p2.age; // Compiles OK; fields access throws at run-time
18 Strings
7 Strings
A string is an object of the predefined class String from namespace System. The keyword string is
an alias for System.String. A string constant is a sequence of characters within double quotes, such
as "New York", "B52", or the empty string "". Internally, a character is stored as a number using the
Unicode character encoding, whose character codes 0–127 coincide with the ASCII character encoding.
String constants and character constants may use character escape codes:
Escape Code Meaning
\a Alert (bell)
\b Backspace
\t Horizontal tab
\v Vertical tab
\n New line
\f Form feed (page break)
\r Carriage return
\" The double quote character
\’ The single quote character
\\ The backslash character
\0 The NUL character (ASCII or Unicode 0)
\xd The character whose character code is the hexadecimal number d
\xdd The character whose character code is the hexadecimal number dd
\xddd The character whose character code is the hexadecimal number ddd
\xdddd The character whose character code is the hexadecimal number dddd
\udddd The character with four-digit hexadecimal Unicode encoding dddd
\Udddddddd The character with eight-digit hexadecimal Unicode encoding dddddddd
A character escape sequence represents a single character. Since the letter A has code 65 (decimal), which
is written 41 in hexadecimal, the string constant "A\x41\u0041\U00000041" is the same as "AAAA". The
\Udddddddd escape code can be used only in string constants, not in character constants.
A verbatim string constant is a string constant prefixed with the @ character. Any escape sequence in
such a string denotes itself, just like ordinary characters, except that "" denotes the double quote character.
Let s1 and s2 be expressions of type String:
• s1.ToString() simply returns s1 itself, and somewhat surprisingly, so does s1.Clone(), whereas
String.Copy(s1) produces a new String object containing the same sequence of characters as s1.
• s1.Length of type int is the length of s1, that is, the number of characters in s1.
• s1[i] of type char is the character at position i in s1, counting from 0. If the index i is less than 0,
or greater than or equal to s1.Length, then the exception IndexOutOfRangeException is thrown.
• s1.Equals(s2) of type bool is true if both s1 and s2 are non-null and contain the same sequence
of characters. Uppercase and lowercase characters are considered distinct.
• s1 == s2 is true if both s1 and s2 are null, or if both are non-null and s1.Equals(s2); and the
inequality s1 != s2 has the same meaning as !(s1 == s2). Hence s1 != "" is true when s1 is
a non-empty string, but also when s1 is null.
Strings 19
where index is a non-negative integer 0, 1, . . . specifying which value is to be formatted, and align is an
integer whose absolute value specifies the minimum number of characters in the resulting string. When
align is positive, the string to be formatted is right-justified (padded on the left) if shorter than the mini-
mum width, and when align is negative, the string to be formatted is left-justified (padded on the right) if
shorter than the minimum width. The code is a formatting pattern (sections 7.2.1 and 7.2.2).
Let fmt be a string that contains one or more format specifications, and let v0, v1, . . . , vn be values of
any type:
• String.Format(fmt, v0, v1, ...) of type String is fmt in which the format specifications
with index 0, 1, . . . are replaced by the formatted string representations of v0, v1, . . . , according to
the format specifications in fmt.
If the type of vi is DateTime or a numeric type (section 5.1), the format specification {i,align:code} is
replaced by the result of formatting vi using code, as shown in sections 7.2.1 and 7.2.2 and the associ-
ated examples. Otherwise the format specification is replaced with vi.ToString(). In both cases, the
resulting string is aligned as specified by align.
The String.Format method throws a FormatException if the index of a format specification is less
than 0 or greater than n, or if a formatting code in fmt is invalid.
The String.Format method is usually not called explicitly but it is called implicitly from
• Console.WriteLine(String fmt, Object v) and its overloads (example 26), and from other
similar output stream methods (section 25);
• AppendFormat(String fmt, Object v) and its overloads (section 8).
String formatting is culture-sensitive: The actual characters used for decimal points, thousand separator,
currency symbols, and so on, and the actual date formatting patterns, weekday names, month names, and
so on, depend on the NumberFormat and DateTimeFormat properties of the CurrentCulture property
of the current thread (example 30). The culture also affects the parsing of floating-point numbers. A
culture is represented by an object of class CultureInfo, and the culture of the current thread is either
determined externally by the operating environment or set explicitly in the source code. For instance, to
use the predefined U.S. English culture:
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Strings 23
int i = 250662;
String s = String.Format("|{0,10:X}|{1,10}|{2:X}|{3}|", i, i, i, i);
The code part of a format specification for a value of a numeric type may also be a custom number
formatting pattern, which is a combination of one or more of the following predefined custom number
formatting codes:
See example 29 and the .Net Framework class library documentation for details.
The code part of a format specification for an object of type DateTime may also be a custom DateTime
formatting pattern, which is a combination of one or more of the many predefined custom DateTime
formatting codes. See the .Net Framework documentation for details.
Strings 25
Format Specifications
Number {0:D4} {0,7} {0:F0} {0:F2} {0,8:F3} {0:E4} {0,9:C}
0 0000 0 0 0.00 0.000 0.0000E+000 $0.00
1 0001 1 1 1.00 1.000 1.0000E+000 $1.00
145 0145 145 145 145.00 145.000 1.4500E+002 $145.00
-1 -0001 -1 -1 -1.00 -1.000 -1.0000E+000 ($1.00)
2.5 2.5 3 2.50 2.500 2.5000E+000 $2.50
-1.5 -1.5 -2 -1.50 -1.500 -1.5000E+000 ($1.50)
330.8 330.8 331 330.80 330.800 3.3080E+002 $330.80
1234.516 1234.516 1235 1234.52 1234.516 1.2345E+003 $1,234.52
Format Specifications
Number {0:000.0} {0:###.#} {0:##0.0} {0:#0E+0} {0:00##;’(neg)’;’-’}
1230.1 1230.1 1230.1 1230.1 12E+2 1230
17 017.0 17 17.0 17E+0 0017
0.15 000.2 .2 0.2 15E-2 -
0 000.0 0.0 00E+0 -
-26 -026.0 -26 -26.0 -26E+0 (neg)
8 String Builders
A string builder, which is an object of class System.Text.StringBuilder, is an extensible and modifiable
string. Characters can be appended to a string builder without copying those characters already in the
string builder; the string builder is automatically and efficiently extended as needed.
By contrast, a String object s1, once created, cannot be modified. Using s1 + s2, one can append s1
and s2, but that creates a new string object by copying all the characters from s1 and s2; there is no way
to extend s1 itself by appending more characters to it. Thus to concatenate n strings each of length k by
repeated string concatenation (+), one must copy k + 2k + 3k + · · · + nk = kn(n + 1)/2 characters, and the
time required to do this is proportional to n2 , which grows rapidly as n grows.
Using a string builder, the concatenation of n strings each of length k requires only time proportional
to n, considerably faster than n2 for large n. To gradually build a string, use a string builder, especially for
repeated concatenation in a loop, as in examples 20 and 31. The expression s1 + · · · + sn is efficient; it
actually means new StringBuilder().Append(s1). . . . .Append(sn).ToString().
Let sb be a StringBuilder, s a String, and v an expression of any type:
Method Append is fast, but Remove and Insert may be slow when they need to move large parts of the
string builder’s contents, that is, when both i and i+n are much smaller than Length.
More StringBuilder methods are described in the .Net Framework class library (section 34).
String Builders 27
class StringBuilderConcatenate {
public static void Main(String[] args) {
StringBuilder res = new StringBuilder();
for (int i=0; i<args.Length; i++)
res.Append(args[i]);
Console.WriteLine(res.ToString());
}
}
9 Arrays
An array is an indexed collection of zero or more variables, called elements. An array has a given element
type t, which can be any type. The value of an expression of an array type such as t[] is either null or a
reference to an array whose element type u is t or implicitly convertible to t. If t is a value type, u must
equal t. Assignment of an array to a variable assigns only the reference; it does not copy the array, as
illustrated by arr1 and arr2 in example 71.
The rank of an array is the number of index expressions required to access an element. Although
an array of rank n is sometimes called an n-dimensional array, note that a Java-style “multidimensional”
array of type t[]...[] is actually an array of rank 1 whose elements happen to be arrays (section 9.2.2).
where is an expression of type int. This creates a new array with rank 1, also called a one-dimensional
array, with elements, all initialized with the default value for type t (section 6.2). The size argument
may be zero, but if it is negative then OverflowException is thrown.
The second form of array creation expression explicitly lists the elements of the new array:
new t[] { expression, ..., expression }
The type of each expression must be implicitly convertible to t. This array creation expression is evaluated
by creating a new array of rank 1 whose length equals the number of expressions. Then the expressions
are evaluated from left to right, and their values are converted to type t and stored in the array.
A local variable or field of array type may be initialized at declaration, by assigning null or an array
to it. When an array creation expression is used to initialize an array variable at its declaration, new t[]
may be left out, so these two declarations are equivalent:
t[] a = new t[] { expression, ..., expression };
t[] a = { expression, ..., expression };
Note that the declared variable a cannot occur in expression: it has not yet been initialized when the
expressions are being evaluated. Also note that there are no array constants: a new distinct array is
created every time an array creation expression is evaluated.
Let a be an array expression of type t[] whose value is an array of length with element type u. Then
the array access expression a[i] denotes element number i of a, counting from 0; this expression has
type t. The integer expression i is called the array index. If the value of i is less than 0 or greater than or
equal to , then an IndexOutOfRangeException is thrown.
When the element type u is a reference type, then every array element assignment a[i] = e checks
that the value of e is null or is implicitly convertible to the element type u. If this is not the case, then
an ArrayTypeMismatchException is thrown. This check is made before every array element assignment
at run-time, but only for reference types. For value types, the type check is performed at compile-time.
Arrays 29
static readonly int[] days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static bool CheckDate(int mth, int day)
{ return (mth >= 1) && (mth <= 12) && (day >= 1) && (day <= days[mth-1]); }
where 1 , . . . , n are expressions of type int, as for one-dimensional arrays. This creates an array with
1 · 2 · · · · · n elements, all initialized with the default value for type t (section 6.2). Alternatively, an array
creation expression for a rectangular n-dimensional array may have this form:
new t[,...,] { ... { expression,...,expression }, { expression,...,expression }, ... }
where there are n − 1 commas in t[,...,] and the nesting depth of curly braces is n. The expressions
are evaluated from left to right and implicitly converted to type t, as for one-dimensional arrays.
To access an element of an n-dimensional rectangular array a, use n index expressions: a[i1 ,...,in ].
This creates a one-dimensional array with 1 elements, all initialized to null, and all of type t[]...[],
where there are h − 1 empty square brackets []. One may subsequently create arrays of type t[]...[]
and assign them to the elements of the one-dimensional array.
To access an element of an h-dimensional jagged array a, use h index expressions: a[i1 ][i2 ]...[in ].
Element access in a jagged array is likely to be less efficient than in a rectangular array.
Arrays 31
double[] row0 = { 0.0 }, row1 = { 1.0, 1.1 }, row2 = { 2.0, 2.1, 2.2 };
double[][] t1 = { row0, row1, row2 };
double[][] t2 = { new double[] {0.0},
new double[] {1.0, 1.1},
new double[] {2.0, 2.1, 2.2}};
double[][] t3 = new double[3][]; // Creates first-dimension array
for (int i=0; i<3; i++) {
t3[i] = new double[i+1]; // Creates second-dimension arrays
for (int j=0; j<=i; j++)
t3[i][j] = i + 0.1 * j;
}
// double[][] t4 = new double[3][3]; // Illegal array creation
• a.Length of type int is the length of a, that is, the total number of elements in a, if a is a one-
dimensional or a rectangular multidimensional array, or the number of elements in the first dimen-
sion of a, if a is a jagged array.
• a.Rank of type int is the rank of a (sections 9 and 9.2.2).
• a.GetEnumerator() of type IEnumerator is a non-generic enumerator (section 27.2) for iterating
through a. This enables the foreach statement to iterate over an array (section 13.6.2 and exam-
ple 40). If a is a one-dimensional array of type t[], one can get a type-safe generic enumerator of
type IEnumerator<t> by computing ((IList<t>)a).GetEnumerator().
• a.GetLength(i) of type int is the number of elements in dimension i (examples 27 and 39).
• a.SetValue(o, i1,..,in) of type void performs the same assignment as a[i1,...,in] = o
when a has rank n; and a.GetValue(i1,...,in) of type Object is the same as a[i1,...,in].
More precisely, if a[i1,...,in] has reference type, then GetValue returns the same reference;
otherwise it returns a boxed copy of the value of a[i1,...,in].
• a.Equals(o) of type bool returns true if a and o refer to the same array object, otherwise false.
Class Array provides static utility methods, some of which are listed below. These methods can be used on
the ordinary array types t[] which derive from class Array. The methods throw ArgumentNullException
if the given array a is null, and throw RankException if a is not one-dimensional.
Color: Iridescent steel blue with deep red fins. Sex determined same
as Silver Tetra.
Breeding Habits: Egg layers. Use large tank, cover bottom with fine
plants, and ample tall ones. Fish spawn at surface, some eggs
adhering to tall plants, others falling. Remove parents. Fry appear
in about 24 hours. Feed Brine Shrimp. Fry grow rapidly.
Temperament: Peaceful.
Maturity: 6 to 8 months.
16
Color: TETRA FROM RIO—body bright silver—3 black bars near head;
fins brilliant red edged with black; black edge on anal of male
wider than on female. During mating season red runs well into
body. TETRA FROM BUENOS AIRES—body bright silver, fins blood
red. Large diamond shaped spot at base of caudal. Sex determined
same as Silver Tetra.
17
average size
Color: Silvery body, caudal reddish, anal and dorsal light yellow with
dark spot. Difficult to distinguish sex.
FEATHERFIN: HEMIGRAMMUS
UNILINEATUS
Color: Like above Pristella Riddlei but has a black and white line down
the anal fin.
18
JEWEL FISH: HEMICHROMIS
BIMACULATUS
(Africa)
average size
Color: Body bright scarlet blending to rich olive on back. Emerald dots
(jewels) in irregular lines cover body and vertical fins. Frequently
difficult to obtain mated pair.
* * * * * * * *
19
Reduced
Color: Bright silver, black bars, body very thin. Black bars disappear
when disturbed or frightened. Difficult to distinguish sex.
Maturity: One to one and a half years. Growth depends upon quality
and quantity of food and size of tank. Angel fish should have as
much live food as possible, largest tank available.
20
Color: Yellowish brown with several dark vertical bands. One of these
bands widens in center of the body into a spot. Lines of shining
blue dots cover the entire body. Dorsal, anal and caudal are wine
red with rows of blue and blue-green spots. Both sexes similar,
female slightly subdued in color.
21
Maturity: 12 to 14 months.
22
Color: Silvery olive with black spot in center of body, another at caudal
base—the eye making the third spot.
Maturity: 10 months.
Maturity: 8 to 10 months.
23
PARADISE: MACROPODUS
OPERCULARIS
(South China)
average size
Color: Body dark with vertical bars of deep red against bluish green
background. Fins similar in color, caudal deep red. Female—shorter
fins, color very pale during mating.
24
average size
Maturity: 8 to 10 months.
25
Color: Male, rich deep greenish olive, sides covered with rows of
gleaming red and green spots, anal bright orange and red. Dorsal
and caudal are of similar colors. Female—dull with light orange
fins.
Breeding Habits: Egg layers, spawn readily in small tank, riccia being
a favorite plant for this purpose.
Temperament: peaceful.
Temperament: Peaceful.
26
Color: Shining olive green, towards the anal: yellowish to white. Body
covered with dark spots changing according to the surroundings.
Average size: 1 to 2 inches.
Breeding Habits: Egg layer. Distinguishing sex marks: male smaller
than female, and has pointed ventral fins, which are in the female,
rounded. Best breeding results are obtained in a large aquarium.
Two to three males for one female. Temperature 75 to 80 degrees.
60 to 500 eggs are carried by female in her ventral fins to a clean
spot which can be the glass of the aquarium, a plant or stone.
Babies hatch after 6 to 9 days. The opinion of breeders is divided
as to whether parents should be removed. Good results were
obtained either way.
Temperament: Paleatus Catfish are the most peaceful fish and very
essential for the maintenance of every balanced aquarium. They
are regarded as the officers of the “Dept. of Sanitation” among
successful aquarists. Paleatus is a ground fish, tirelessly picking up
food remnants and left-overs which other fish do not eat. Through
this activity, Paleatus helps to keep the food particles from
contaminating the water. Catfish dart up to the surface to breathe
atmospheric air.
27
Breeding Habits: Just like their original form, the Red Paradise. The
albino color breeds true. (See page 23.)
Breeding Habits and Temperament also like Tetra from Rio. (see
page 16.)
Breeding Habits: Heartier and more easily bred than ordinary Black
Mollies.
28
GOLD FISH:
Veiltail
History: The Gold Fish, the oldest and most popular of our numerous
Aquarium Fish, was developed by the Chinese during the Sung
Dynasty (960-1278) from the wild Carassius Auratus to the various
varieties now familiar to us.
Breeding Hints: During the breeding season which falls during the
first seven months of the year, the male will show small warts of
pin point size on his gill plates. The female is shorter than the male
but fuller in body, more so, when carrying spawn. A mature fish is
about 3-10 inches long, depending on type and a pair must
therefore have a breeding aquarium of at least 10 gallons. The fish
will spawn on myriophyllum, long rooted water hyacinths, or other
soft bunchy plants and the eggs will hatch in about 4-7 days. Since
the parent fish like to eat their own spawn, it is therefore advisable
to remove either the parents or the plants with their adhering
eggs. The newly hatched babies are fed with infusoria and later on
with fish food of a fine grain.
Diseases: Fin Congestion and Fungus are the most frequent Goldfish
diseases. Their best cure is the salt treatment which is described
on page 33.
30
TURTLES
Baby turtles are very easily kept as pets and require little care. While in
captivity, Turtles will forget their time schedule and will not hibernate.
Any round or oval bowl, an aquarium or a flat pan with a rim
sufficiently high to prevent the turtle from crawling out, is an adequate
home. In this container, place white or colored pebbles, and in the
center a flat stone. Fill the container with clean water of room
temperature (60 to 80 degrees, fahrenheit) but see to it that the stone
is not covered by the water for it will serve as an “Island” and thus give
the turtle a chance to leave the wet element when desired. The best
place for the bowl is in a light place, but special care should be taken to
see that the bowl is not exposed too long to the direct sun. Ant Eggs,
commonly packed as “Turtle Food” will mainly be their diet but lean raw
beef, which is finely scraped, will be an appreciated change. The same
applies for green lettuce, rainworms, etc. A variation in food and
sunshine will prevent blindness, but should a turtle get a white film
over its eyes, a few drops of Cod liver Oil forced by a medicine dropper
in its mouth, might help. Boric acid swabbed over the eyes will also be
beneficial. Turtles will not feed “on land” therefore all food should be
placed in the water. Water should be changed two to three times
weekly.
31
HEALTH
It is much easier to keep fish healthy than to cure them.
Fish in good health are active and keep dorsal fin erect. (Folded fins for
a short period do not mean a sick fish.)
Most fish ills develop from chills. Keep fish above lowest safe
temperature. Young fry especially should be kept warm.
Do not crowd fish—be sure plants are thriving and there is ample
oxygen in water.
Fish constantly at top indicate foul water and lack of oxygen. Remove
part of water and replace with fresh of same temperature.
Dying plants cause much trouble—be sure plants are healthy and
growing.
Vary the diet for the fish. Feed only as much as they will eat in ten
minutes. Feed sparingly and several times a day if necessary. Use glass
feeding ring. (Fig. 4). All uneaten food drops to one spot where it can
be easily removed with a dip tube.
Health and growth of fry depend upon oxygen supply. Use tank with
large air surface. BE SURE AND DO NOT CROWD YOUNG FRY.
Crowding stunts growth and frequently causes disease, and loss of
whole brood. Fry demand approximately same amount of water as
adults—see page 31.
FIG·4
Never give fish more food than they can clean up in ten minutes.
32
FOOD
Do Not Overfeed—Never give fish more food than they can clean up
in ten minutes.
Vary the Diet—Have several kinds of food on hand at all times. Dried
Shrimp, Dried Daphnae, scrapings from raw beef, bits of canned
salmon, bits of boiled spinach, finely crumbed graham cracker, bits of
yolk of boiled egg, and most of the prepared foods are excellent but
should be supplemented with some form of live food. Once a week
they should be fed chopped earth worms or Enchytrae (White worms).
Feed live bearer’s fry small quantity of fine foods several times a day.
Feed egg layer’s fry Brine Shrimp twice a day the first couple weeks
and then feed same as live bearer’s fry.
Tubifex worms are found in fresh water streams and rivers, close to
shore in soft loamy bottom. They are an excellent live food provided
they are fed to the fish with care. Keep in cool place in container
having large air surface with just enough water to cover them. Since
they bury themselves in the gravel, it is best to feed them to the fish
with a worm feeder. The best type of feeder has a quantity of small
holes through which the worms wriggle into the mouths of the fish
eagerly waiting below. For baby fish it is best to cut the worms into
small pieces.
Enchytrae (White Worms) multiply rapidly in a wooden box (about
10″ square) filled with about 5″ of rich loamy soil. Portion of worms is
placed in soil and whole mass kept fairly moist. Feed slice of bread
soaked in sweet or sour milk every 3 or 4 days. Be sure all food is
covered with at least 1″ of soil. Before feeding be sure all old food is
consumed. They may be fed cooked oatmeal or mashed potatoes
WITHOUT SALT. Stir soil once a week to aerate it and prevent souring.
Cover soil with piece of glass to keep moisture in. Keep in cool dark
place.
33