Code Listings 2
Code Listings 2
class Octopus
{
string name;
public int Age = 10;
static readonly int legs = 8, eyes = 1;
}
Fields - readonly
class Octopus
{
public readonly string Name;
public readonly int Legs = 8;
// Constants are factored out at compile-time and baked into the calling site.
Test.Message.Dump();
Methods - Expression-bodied
Foo1 (10).Dump();
Foo2 (10).Dump();
Local methods
void Main()
{
WriteCubes();
}
void WriteCubes()
{
Console.WriteLine (Cube (3));
Console.WriteLine (Cube (4));
Console.WriteLine (Cube (5));
int x = 3;
Foo();
Methods - Overloading
void Main()
{
Foo (123); // int
Foo (123.0); // double
Foo (123, 123F); // int, float
Foo (123F, 123); // float, int
}
void Main() {}
Constructors
Constructors - Overloading
Constructors - Nonpublic
Class1 c1 = Class1.Create(); // OK
Class1 c2 = new Class1(); // Error: Will not compile
Deconstructors
class Rectangle
{
public readonly float Width, Height;
Object Initializers
// Object initialization syntax. Note that we can still specify constructor arguments:
b1.Dump(); b2.Dump();
public Bunny () {}
public Bunny (string n) { Name = n; }
}
// Instead of using object initializers, we could make Bunny’s constructor accept optional parameters.
// This has both pros and cons (see book):
b.Dump();
public Bunny (
string name,
bool likesCarrots = false,
bool likesHumans = false)
{
Name = name;
LikesCarrots = likesCarrots;
LikesHumans = likesHumans;
Properties
// Properties look like fields from the outside but internally, they contain logic, like methods:
Properties - expression-bodied
// From C# 7, we can take this further, and write both the get and set accessors in
// expression-bodied syntax:
public decimal Worth2
{
get => currentPrice * sharesOwned;
set => sharesOwned = value / currentPrice;
}
Automatic Properties
Property Initializers
// In this example, the set accessors are private while the get accessors are public:
Indexers
class Sentence
{
string[] words = "The quick brown fox".Split();
// In C# 8, we can also define indexers that use the Index & Range types:
public string this [Index index] => words [index];
public string[] this [Range range] => words [range];
// From C# 12, you can include a parameter list directly after a class (or struct) declaration.
// This instructs the compiler to automatically build a primary constructor using the primary
// constructor parameters (firstName and lastName).
// The constructor that C# builds is called primary because any additional constructors
// that you choose to (explicitly) write must invoke it:
public void Print() => Console.WriteLine (firstName + " " + lastName + " " + _age);
}
// The accessibility of primary constructor parameters extends to field and property initializers.
// In the following example, we use field and property initializers to assign firstName to a public
// field, and lastName to a public property:
Static Constructors
// A static constructor executes once per type, rather than once per instance:
class Test
{
static Test()
{
Console.WriteLine ("Type Initialized");
}
}
// Static field initializers run just before the static constructor is called:
Foo.X.Dump ("X"); // 0
Foo.Y.Dump ("Y"); // 3
class Foo
{
public static int X = Y; // 0
public static int Y = 3; // 3
}
Console.WriteLine (Foo.X); // 3
class Foo
{
public static Foo Instance = new Foo();
public static int X = 3;
Partial Types
Partial Methods
// A partial type may contain partial methods. These let an auto-generated partial type
// provide customizable hooks for manual authoring.
// The presence of an accessiblity modifier on a partial method denotes an 'extended partial method'.
// Extended partial methods *must* have implementations:
Inheritance
Structs
Access Modifiers
Interfaces
Enums
Nested Types
Generics
C# 12
in a Nutshell
About the Book
Code Listings
C# 12 in a Nutshell
C# 10 in a Nutshell
C# 9.0 in a Nutshell
C# 8.0 in a Nutshell
C# 7.0 in a Nutshell
Extras
Contact