Chapter 2 - C# Language Basics
A First C# Program
A First C# Program
int x = 12 * 30;
System.Console.WriteLine (x);
A First C# Program with using directive
using System;
int x = 12 * 30;
Console.WriteLine (x);
First Program Refactored
Console.WriteLine (FeetToInches (30));
Console.WriteLine (FeetToInches (100));
int FeetToInches (int feet)
{
int inches = feet * 12;
return inches;
}
Method with no input or output
SayHello();
void SayHello()
{
Console.WriteLine ("Hello, world");
}
A First C# Program - without top-level statements
using System;
class Program
{
static void Main()
{
Console.WriteLine (FeetToInches (30));
Console.WriteLine (FeetToInches (100));
}
static int FeetToInches (int feet)
{
int inches = feet * 12;
return inches;
}
}
Syntax Basics
The @ prefix
int @class = 123;
string @namespace = "foo";
Contextual Keywords
int add = 3;
bool ascending = true;
int yield = 45;
Semicolons and Comments
Console.WriteLine
(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10);
int x = 3;
int y = 3;
Type Basics
Predefined Type Examples
string message = "Hello world";
string upperMessage = message.ToUpper();
Console.WriteLine (upperMessage);
int x = 2015;
message = message + x.ToString();
Console.WriteLine (message);
bool simpleVar = false;
if (simpleVar)
Console.WriteLine ("This will not print");
int y = 5000;
bool lessThanAMile = y < 5280;
if (lessThanAMile)
Console.WriteLine ("This will print");
Custom Type Examples
UnitConverter feetToInchesConverter = new UnitConverter (12);
UnitConverter milesToFeetConverter = new UnitConverter (5280);
Console.WriteLine (feetToInchesConverter.Convert (30));
Console.WriteLine (feetToInchesConverter.Convert (100));
Console.WriteLine (feetToInchesConverter.Convert (milesToFeetConverter.Convert (1)));
public class UnitConverter
{
int ratio;
public UnitConverter (int unitRatio) { ratio = unitRatio; }
public int Convert (int unit) { return unit * ratio; }
}
Instance vs Static Members
Panda p1 = new Panda ("Pan Dee");
Panda p2 = new Panda ("Pan Dah");
Console.WriteLine (p1.Name);
Console.WriteLine (p2.Name);
Console.WriteLine (Panda.Population);
public class Panda
{
public string Name;
public static int Population;
public Panda (string n)
{
Name = n;
Population = Population + 1;
}
}
Defining a namespace
using Animals;
Panda p = new Panda ("Pan Dee");
Console.WriteLine (p.Name);
namespace Animals
{
public class Panda
{
public string Name;
public Panda (string n)
{
Name = n;
}
}
}
Defining a Main method
using System;
class Program
{
static void Main()
{
int x = 12 * 30;
Console.WriteLine (x);
}
}
Conversions
int x = 12345;
long y = x;
short z = (short)x;
x.Dump ("x");
y.Dump ("y");
z.Dump ("z");
Value Types
Point p1 = new Point();
p1.X = 7;
Point p2 = p1;
Console.WriteLine (p1.X);
Console.WriteLine (p2.X);
p1.X = 9;
Console.WriteLine (p1.X);
Console.WriteLine (p2.X);
public struct Point { public int X, Y; }
Reference Types
Point p1 = new Point();
p1.X = 7;
Point p2 = p1;
Console.WriteLine (p1.X);
Console.WriteLine (p2.X);
p1.X = 9;
Console.WriteLine (p1.X);
Console.WriteLine (p2.X);
public class Point { public int X, Y; }
Null
Point p = null;
Console.WriteLine (p == null);
Console.WriteLine (p.X);
public class Point { public int X, Y; }
Nulls with structs
Point p = null;
int x = null;
public struct Point { public int X, Y; }
Storage Overhead
unsafe static void Main()
{
sizeof (Point).Dump();
sizeof (A).Dump();
}
struct Point
{
int x;
int y;
}
struct A
{
byte b;
long l;
}
Numeric Types
Numeric Types
int i = -1;
i.Dump();
byte b = 255;
b.Dump();
double d = 1.23;
d.Dump();
Numeric Literals
int x = 127;
long y = 0x7F;
int million = 1_000_000;
var b = 0b1010_1011_1100_1101_1110_1111;
double d = 1.5;
double doubleMillion = 1E06;
Console.WriteLine ( 1.0.GetType());
Console.WriteLine ( 1E06.GetType());
Console.WriteLine ( 1.GetType());
Console.WriteLine (0xF0000000.GetType());
Console.WriteLine (0x100000000.GetType());
Numeric Suffixes
long i = 5;
double x = 4.0;
float f = 4.5F;
decimal d = -1.23M;
Numeric Conversions
int x = 12345;
long y = x;
short z = (short)x;
int i = 1;
float f = i;
int iExplicit = (int)f;
int i1 = 100000001;
float f1 = i1;
int i2 = (int)f1;
Increment and Decrement Operators
int x = 0, y = 0;
Console.WriteLine (x++);
Console.WriteLine (++y);
Integral Division
int a = 2 / 3;
int b = 0;
int c = 5 / b;
Integral Overflow
int a = int.MinValue;
a--;
Console.WriteLine (a == int.MaxValue);
Overflow Checking
int a = 1000000;
int b = 1000000;
int c = checked (a * b);
checked
{
int c2 = a * b;
c2.Dump();
}
Overflow Checking with Constant Expressions
int x = int.MaxValue + 1;
int y = unchecked (int.MaxValue + 1);
8- and 16-bit literals
short x = 1, y = 1;
short z = x + y;
short z = (short) (x + y);
Native-sized integers
nint x = 123;
nint y = 234;
nint product = x * y;
product.Dump();
IntPtr p = x;
y = p;
Special float and double Values
Console.WriteLine (double.NegativeInfinity);
Console.WriteLine ( 1.0 / 0.0);
Console.WriteLine (-1.0 / 0.0);
Console.WriteLine ( 1.0 / -0.0);
Console.WriteLine (-1.0 / -0.0);
Console.WriteLine ( 0.0 / 0.0);
Console.WriteLine ((1.0 / 0.0) - (1.0 / 0.0));
Console.WriteLine (0.0 / 0.0 == double.NaN);
Console.WriteLine (double.IsNaN (0.0 / 0.0));
Console.WriteLine (object.Equals (0.0 / 0.0, double.NaN));
Real Number Rounding Errors
{
float x = 0.1f;
Console.WriteLine (x + x + x + x + x + x + x + x + x + x);
}
{
decimal y = 0.1m;
Console.WriteLine (y + y + y + y + y + y + y + y + y + y);
}
decimal m = 1M / 6M;
double d = 1.0 / 6.0;
m.Dump ("m"); d.Dump ("d");
decimal notQuiteWholeM = m+m+m+m+m+m;
double notQuiteWholeD = d+d+d+d+d+d;
Console.WriteLine (notQuiteWholeM == 1M);
Console.WriteLine (notQuiteWholeD < 1.0);
Boolean Type and Operators
Equality and Comparison Operators
int x = 1;
int y = 2;
int z = 1;
Console.WriteLine (x == y);
Console.WriteLine (x != y);
Console.WriteLine (x == z);
Console.WriteLine (x < y);
Console.WriteLine (x >= z);
Equality with Reference Types
Dude d1 = new Dude ("John");
Dude d2 = new Dude ("John");
Console.WriteLine (d1 == d2);
Dude d3 = d1;
Console.WriteLine (d1 == d3);
public class Dude
{
public string Name;
public Dude (string n) { Name = n; }
}
And & Or Operators
UseUmbrella (true, false, false).Dump();
UseUmbrella (true, true, true).Dump();
bool UseUmbrella (bool rainy, bool sunny, bool windy)
{
return !windy && (rainy || sunny);
}
Shortcircuiting
StringBuilder sb = null;
if (sb != null && sb.Length > 0)
Console.WriteLine ("sb has data");
else
Console.WriteLine ("sb is null or empty");
And & Or Operators - non-shortcircuiting
UseUmbrella (true, false, false).Dump();
UseUmbrella (true, true, true).Dump();
StringBuilder sb = null;
if (sb != null & sb.Length > 0)
Console.WriteLine ("sb has data");
else
Console.WriteLine ("sb is null or empty");
bool UseUmbrella (bool rainy, bool sunny, bool windy)
{
return !windy & (rainy | sunny);
}
Conditional operator (ternary)
Max (2, 3).Dump();
Max (3, 2).Dump();
int Max (int a, int b)
{
return (a > b) ? a : b;
}
Strings and Characters
Character literals
char c = 'A';
char newLine = '\n';
char backSlash = '\\';
c.Dump();
(backSlash.ToString() + newLine.ToString() + backSlash.ToString()).Dump();
Character conversions
ushort us = 'a';
int i = 'z';
us.Dump();
i.Dump();
short s = (short) 'a';
s.Dump();
String literals
string h = "Heat";
string a = "test";
string b = "test";
Console.WriteLine (a == b);
string t = "Here's a tab:\t";
string a1 = "\\\\server\\fileshare\\helloworld.cs";
a1.Dump ("a1");
string a2 = @"\\server\fileshare\helloworld.cs";
a2.Dump ("a2");
string escaped = "First Line\r\nSecond Line";
string verbatim = @"First Line
Second Line";
Console.WriteLine (escaped == verbatim);
string xml = @"<customer id=""123""></customer>";
xml.Dump ("xml");
String concatenation
string s1 = "a" + "b";
s1.Dump();
string s2 = "a" + 5;
s2.Dump();
String interpolation
int x = 4;
Console.WriteLine ($"A square has {x} sides");
string s = $"255 in hex is {byte.MaxValue:X2}";
s.Dump ("With a format string");
x = 2;
s = $@"this spans {
x} lines";
s.Dump ("Verbatim multi-line interpolated string");
Arrays
Arrays
char[] vowels = new char[5];
vowels [0] = 'a';
vowels [1] = 'e';
vowels [2] = 'i';
vowels [3] = 'o';
vowels [4] = 'u';
Console.WriteLine (vowels [1]);
for (int i = 0; i < vowels.Length; i++)
Console.Write (vowels [i]);
char[] easy = {'a','e','i','o','u'};
easy.Dump();
Default Element Initialization
int[] a = new int[1000];
Console.Write (a [123]);
Default Element Initialization - Reference Types
Point[] a = new Point [1000];
for (int i = 0; i < a.Length; i++)
a [i] = new Point();
Point[] nulls = new Point [1000];
Console.WriteLine (nulls [0] == null);
Console.WriteLine (nulls [0].X);
public class Point { public int X, Y; }
Default Element Initialization - Value Types
Point[] a = new Point[1000];
int x = a[500].X;
x.Dump();
public struct Point { public int X, Y; }
Indices
char[] vowels = new char[] {'a','e','i','o','u'};
char lastElement = vowels [^1].Dump();
char secondToLast = vowels [^2].Dump();
Index first = 0;
Index last = ^1;
char firstElement = vowels [first].Dump();
char lastElement2 = vowels [last].Dump();
Ranges
char[] vowels = new char[] { 'a', 'e', 'i', 'o', 'u' };
char[] firstTwo = vowels [..2].Dump();
char[] lastThree = vowels [2..].Dump();
char[] middleOne = vowels [2..3].Dump();
char[] lastTwo = vowels [^2..].Dump();
Range firstTwoRange = 0..2;
char[] firstTwo2 = vowels [firstTwoRange].Dump();
Multidimensional Arrays - Rectangular
int [,] matrix = new int [3, 3];
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix [i, j] = i * 3 + j;
matrix.Dump();
int[,] matrix2 = new int[,]
{
{0,1,2},
{3,4,5},
{6,7,8}
};
matrix2.Dump();
Multidimensional Arrays - Jagged
int [][] matrix = new int [3][];
for (int i = 0; i < matrix.Length; i++)
{
matrix[i] = new int [3];
for (int j = 0; j < matrix[i].Length; j++)
matrix[i][j] = i * 3 + j;
}
matrix.Dump ("Populated manually");
int[][] matrix2 = new int[][]
{
new int[] {0,1,2},
new int[] {3,4,5},
new int[] {6,7,8,9}
};
matrix2.Dump ("Populated via array initialization expression");
Simplified Array Initialization Expressions
char[] vowels = {'a','e','i','o','u'};
int[,] rectangularMatrix =
{
{0,1,2},
{3,4,5},
{6,7,8}
};
int[][] jaggedMatrix =
{
new int[] {0,1,2},
new int[] {3,4,5},
new int[] {6,7,8}
};
rectangularMatrix.Dump(); jaggedMatrix.Dump();
Simplified Array Initialization with Implicit Typing
var i = 3;
var s = "sausage";
var rectMatrix = new int[,]
{
{0,1,2},
{3,4,5},
{6,7,8}
};
var jaggedMat = new int[][]
{
new int[] {0,1,2},
new int[] {3,4,5},
new int[] {6,7,8}
};
var vowels = new[] {'a','e','i','o','u'};
var x = new[] { 1, 10000000000 };
vowels.Dump(); x.Dump();
Bounds Checking
int[] arr = new int[3];
arr[3] = 1;
Variables and Parameters
Stack
Factorial(5).Dump();
static int Factorial (int x)
{
if (x == 0) return 1;
return x * Factorial (x-1);
}
Heap
StringBuilder ref1 = new StringBuilder ("object1");
Console.WriteLine (ref1);
StringBuilder ref2 = new StringBuilder ("object2");
StringBuilder ref3 = ref2;
Console.WriteLine (ref3);
Definite Assignment - Local Variables
int x;
Console.WriteLine (x);
Definite Assignment - Array Elements
int[] ints = new int[2];
Console.WriteLine (ints[0]);
Definite Assignment - Fields
Console.WriteLine (Test.X);
class Test { public static int X; }
Parameters - Passing by Value
int x = 8;
Foo (x);
Console.WriteLine ("x is " + x);
void Foo (int p)
{
p = p + 1;
Console.WriteLine ("p is " + p);
}
Parameters - Passing by Value (reference types)
StringBuilder sb = new StringBuilder();
Foo (sb);
Console.WriteLine (sb.ToString());
static void Foo (StringBuilder fooSB)
{
fooSB.Append ("test");
fooSB = null;
}
Parameters - The ref Modifier
int x = 8;
Foo (ref x);
Console.WriteLine (x);
static void Foo (ref int p)
{
p = p + 1;
Console.WriteLine (p);
}
Parameters - The ref Modifier - Swap Method
string x = "Penn";
string y = "Teller";
Swap (ref x, ref y);
Console.WriteLine (x);
Console.WriteLine (y);
static void Swap (ref string a, ref string b)
{
string temp = a;
a = b;
b = temp;
}
Parameters - The out Modifier
string a, b;
Split ("Stevie Ray Vaughn", out a, out b);
Console.WriteLine (a);
Console.WriteLine (b);
void Split (string name, out string firstNames, out string lastName)
{
int i = name.LastIndexOf (' ');
firstNames = name.Substring (0, i);
lastName = name.Substring (i + 1);
}
Parameters - out variables and discards
Split ("Stevie Ray Vaughan", out string a, out string b);
Console.WriteLine (a);
Console.WriteLine (b);
Split ("Stevie Ray Vaughan", out string x, out _);
Console.WriteLine (x);
void Split (string name, out string firstNames, out string lastName)
{
int i = name.LastIndexOf (' ');
firstNames = name.Substring (0, i);
lastName = name.Substring (i + 1);
}
Parameters - Implications of Passing By Reference
static int x;
static void Main() { Foo (out x); }
static void Foo (out int y)
{
Console.WriteLine (x);
y = 1;
Console.WriteLine (x);
}
Parameters - The in Modifier
void Main()
{
SomeBigStruct x = default;
Foo (x);
Foo (in x);
Bar (x);
Bar (in x);
}
void Foo (SomeBigStruct a) => "Foo".Dump();
void Foo (in SomeBigStruct a) => "in Foo".Dump();
void Bar (in SomeBigStruct a) => "in Bar".Dump();
struct SomeBigStruct
{
public decimal A, B, C, D, E, F, G;
}
Parameters - The params modifier
int total = Sum (1, 2, 3, 4);
Console.WriteLine (total);
int total2 = Sum (new int[] { 1, 2, 3, 4 });
int Sum (params int[] ints)
{
int sum = 0;
for (int i = 0; i < ints.Length; i++)
sum += ints [i];
return sum;
}
Parameters - Optional Parameters
Foo();
Foo (23);
void Foo (int x = 23) { Console.WriteLine (x); }
Parameters - Named Arguments
Foo (x:1, y:2);
Foo (y:2, x:1);
Foo (1, y:2);
void Foo (int x, int y) { Console.WriteLine (x + ", " + y); }
Parameters - Optional Parameters with Named Arguments
Bar (d:3);
void Bar (int a = 0, int b = 0, int c = 0, int d = 0)
{
Console.WriteLine (a + " " + b + " " + c + " " + d);
}
ref locals
int[] numbers = { 0, 1, 2, 3, 4 };
ref int numRef = ref numbers [2];
numRef *= 10;
Console.WriteLine (numRef);
Console.WriteLine (numbers [2]);
ref returns
static string X = "Old Value";
static ref string GetX() => ref X;
static void Main()
{
ref string xRef = ref GetX();
xRef = "New Value";
Console.WriteLine (X);
}
var - Implicitly Typed Variables
{
var x = "hello";
var y = new System.Text.StringBuilder();
var z = (float)Math.PI;
}
{
string x = "hello";
System.Text.StringBuilder y = new System.Text.StringBuilder();
float z = (float)Math.PI;
}
Target-typed new expressions
{
System.Text.StringBuilder sb1 = new();
System.Text.StringBuilder sb2 = new ("Test");
}
{
System.Text.StringBuilder sb1 = new System.Text.StringBuilder();
System.Text.StringBuilder sb2 = new System.Text.StringBuilder ("Test");
}
MyMethod (new ("test"));
void MyMethod (StringBuilder sb) { }
class Foo
{
System.Text.StringBuilder sb;
public Foo (string initialValue)
{
sb = new (initialValue);
}
}
Implicitly Typed Variables are Statically Typed
var x = 5;
x = "hello";
Implicitly Typed Variables and Readability
var sb = new System.Text.StringBuilder();
var z = (float)Math.PI;
Random r = new Random();
var x = r.Next();
Expressions and Operators
Primary Expressions
Math.Log(1)
Assignment Expressions
int x, y;
y = 5 * (x = 2);
x.Dump();
y.Dump();
x *= 2;
x <<= 1;
x.Dump();
Precedence
1 + 2 * 3
Left Associativity
8 / 4 / 2
Right Associativity
int x, y;
x = y = 3;
x.Dump(); y.Dump();
Null Operators
Null Coalescing Operator
string s1 = null;
string s2 = s1 ?? "nothing";
s2.Dump();
Null Coalescing Assignment Operator
string s1 = null;
s1 ??= "something";
Console.WriteLine (s1);
s1 ??= "everything";
Console.WriteLine (s1);
Null-Conditional Operator
System.Text.StringBuilder sb = null;
string s = sb?.ToString();
s.Dump();
string s2 = sb?.ToString().ToUpper();
s2.Dump();
Null-Conditional Operator - with nullable types
System.Text.StringBuilder sb = null;
int? length = sb?.ToString().Length;
length.Dump();
string s = sb?.ToString() ?? "nothing";
s.Dump();
Statements
Declaration Statements
string someWord = "rosebud";
int someNumber = 42;
bool rich = true, famous = false;
Declaration Statements - Constants
const double c = 2.99792458E08;
c += 10;
Declaration Statements - Local Variables
int x;
{
int y;
int x;
}
{
int y;
}
Console.Write (y);
Expression Statements
string s;
int x, y;
System.Text.StringBuilder sb;
x = 1 + 2;
x++;
y = Math.Max (x, 5);
Console.WriteLine (y);
sb = new StringBuilder();
new StringBuilder();
if statement
if (5 < 2 * 3)
Console.WriteLine ("true");
else clause
if (2 + 2 == 5)
Console.WriteLine ("Does not compute");
else
Console.WriteLine ("false");
if (2 + 2 == 5)
Console.WriteLine ("Does not compute");
else
if (2 + 2 == 4)
Console.WriteLine ("Computes");
if (2 + 2 == 5)
Console.WriteLine ("Does not compute");
else if (2 + 2 == 4)
Console.WriteLine ("Computes");
Changing Execution Flow with Braces
if (true)
if (false)
Console.WriteLine();
else
Console.WriteLine ("executes");
if (true)
{
if (false)
Console.WriteLine();
else
Console.WriteLine ("executes");
}
if (true)
{
if (false)
Console.WriteLine();
}
else
Console.WriteLine ("does not execute");
Omitting Braces
TellMeWhatICanDo (55);
TellMeWhatICanDo (30);
TellMeWhatICanDo (20);
TellMeWhatICanDo (8);
static void TellMeWhatICanDo (int age)
{
if (age >= 35)
Console.WriteLine ("You can be president!");
else if (age >= 21)
Console.WriteLine ("You can drink!");
else if (age >= 18)
Console.WriteLine ("You can vote!");
else
Console.WriteLine ("You can wait!");
}
switch Statement
ShowCard (5); ShowCard (11); ShowCard (13);
static void ShowCard (int cardNumber)
{
switch (cardNumber)
{
case 13:
Console.WriteLine ("King");
break;
case 12:
Console.WriteLine ("Queen");
break;
case 11:
Console.WriteLine ("Jack");
break;
case -1:
goto case 12;
default:
Console.WriteLine (cardNumber);
break;
}
}
switch Statement - Stacking Cases
int cardNumber = 12;
switch (cardNumber)
{
case 13:
case 12:
case 11:
Console.WriteLine ("Face card");
break;
default:
Console.WriteLine ("Plain card");
break;
}
switch Statement - patterns
TellMeTheType (12);
TellMeTheType ("hello");
TellMeTheType (true);
void TellMeTheType (object x)
{
switch (x)
{
case int i:
Console.WriteLine ("It's an int!");
Console.WriteLine ($"The square of {i} is {i * i}");
break;
case string s:
Console.WriteLine ("It's a string");
Console.WriteLine ($"The length of {s} is {s.Length}");
break;
default:
Console.WriteLine ("I don't know what x is");
break;
}
}
switch Statement - patterns - predicated
object x = true;
switch (x)
{
case bool b when b == true:
Console.WriteLine ("True!");
break;
case bool b:
Console.WriteLine ("False!");
break;
}
switch Statement - patterns - stacked
object x = 3000m;
switch (x)
{
case float f when f > 1000:
case double d when d > 1000:
case decimal m when m > 1000:
Console.WriteLine ("We can refer to x here but not f or d or m");
break;
}
switch expressions
int cardNumber = 13;
string cardName = cardNumber switch
{
13 => "King",
12 => "Queen",
11 => "Jack",
_ => "Pip card"
};
cardName.Dump();
string suite = "spades";
string cardName2 = (cardNumber, suite) switch
{
(13, "spades") => "King of spades",
(13, "clubs") => "King of clubs",
_ => "Other"
};
cardName2.Dump();
while loop
int i = 0;
while (i < 3)
{
Console.WriteLine (i);
i++;
}
do-while loop
int i = 0;
do
{
Console.WriteLine (i);
i++;
}
while (i < 3);
for loop
for (int i = 0; i < 3; i++)
Console.WriteLine (i);
Console.WriteLine();
for (int i = 0, prevFib = 1, curFib = 1; i < 10; i++)
{
Console.WriteLine (prevFib);
int newFib = prevFib + curFib;
prevFib = curFib; curFib = newFib;
}
foreach loop
foreach (char c in "beer")
Console.WriteLine (c);
break statement
int x = 0;
while (true)
{
if (x++ > 5)
break ;
}
x.Dump();
continue statement
for (int i = 0; i < 10; i++)
{
if ((i % 2) == 0)
continue;
Console.Write (i + " ");
}
goto statement
int i = 1;
startLoop:
if (i <= 5)
{
Console.Write (i + " ");
i++;
goto startLoop;
}
return statement
AsPercentage (0.345m).Dump();
decimal AsPercentage (decimal d)
{
decimal p = d * 100m;
return p;
}
Namespaces
Nesting namespaces
typeof (Outer.Middle.Inner.Class1).FullName.Dump();
namespace Outer
{
namespace Middle
{
namespace Inner
{
class Class1 {}
class Class2 {}
}
}
}
Using directive
using Outer.Middle.Inner;
Class1 c;
namespace Outer
{
namespace Middle
{
namespace Inner
{
class Class1 {}
class Class2 {}
}
}
}
Using static
using static System.Console;
WriteLine ("Hello");
Rules - Name scoping
namespace Outer
{
class Class1 { }
namespace Inner
{
class Class2 : Class1 { }
}
}
namespace MyTradingCompany
{
namespace Common
{
class ReportBase { }
}
namespace ManagementReporting
{
class SalesReport : Common.ReportBase { }
}
}
Rules - Name hiding
namespace Outer
{
class Foo { }
namespace Inner
{
class Foo { }
class Test
{
Foo f1;
Outer.Foo f2;
}
}
}
Rules - Repeated namespaces
namespace Outer.Middle.Inner
{
class Class1 {}
}
namespace Outer.Middle.Inner
{
class Class2 {}
}
Rules - Nested using directive
namespace N1
{
class Class1 {}
}
namespace N2
{
using N1;
class Class2 : Class1 {}
}
namespace N2
{
class Class3 : Class1 { }
}
Aliasing types and namespaces
using PropertyInfo2 = System.Reflection.PropertyInfo;
using R = System.Reflection;
PropertyInfo2 p;
R.PropertyInfo p2;
Namespace alias qualifier
namespace N
{
class A
{
static void Main()
{
new A.B().Dump();
new global::A.B().Dump();
}
public class B { }
}
}
namespace A
{
class B { }
}