Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharpNotesForProfessionals.pdf
Скачиваний:
57
Добавлен:
20.05.2023
Размер:
6.12 Mб
Скачать

Section 72.7: Using static type

The using static [Namespace.Type] directive allows the importing of static members of types and enumeration values. Extension methods are imported as extension methods (from just one type), not into top-level scope.

Version ≥ 6.0

using static System.Console; using static System.ConsoleColor; using static System.Math;

class Program

{

static void Main()

{

BackgroundColor = DarkBlue; WriteLine(Sqrt(2));

}

}

Live Demo Fiddle

Version < 6.0

using System;

class Program

{

static void Main()

{

Console.BackgroundColor = ConsoleColor.DarkBlue; Console.WriteLine(Math.Sqrt(2));

}

}

Section 72.8: Index initializers

Index initializers make it possible to create and initialize objects with indexes at the same time.

This makes initializing Dictionaries very easy:

var dict = new Dictionary<string, int>()

{

["foo"] = 34, ["bar"] = 42

};

Any object that has an indexed getter or setter can be used with this syntax:

class Program

{

public class MyClassWithIndexer

{

public int this[string index]

{

set

{

Console.WriteLine($"Index: {index}, value: {value}");

}

}

}

GoalKicker.com – C# Notes for Professionals

433

public static void Main()

{

var x = new MyClassWithIndexer()

{

["foo"] = 34, ["bar"] = 42

};

Console.ReadKey();

}

}

Output:

Index: foo, value: 34

Index: bar, value: 42

View Demo

If the class has multiple indexers it is possible to assign them all in a single group of statements:

class Program

{

public class MyClassWithIndexer

{

public int this[string index]

{

set

{

Console.WriteLine($"Index: {index}, value: {value}");

}

}

public string this[int index]

{

set

{

Console.WriteLine($"Index: {index}, value: {value}");

}

}

}

public static void Main()

{

var x = new MyClassWithIndexer()

{

["foo"] = 34, ["bar"] = 42, [10] = "Ten",

[42] = "Meaning of life"

};

}

}

Output:

Index: foo, value: 34

Index: bar, value: 42

GoalKicker.com – C# Notes for Professionals

434

Index: 10, value: Ten

Index: 42, value: Meaning of life

It should be noted that the indexer set accessor might behave di erently compared to an Add method (used in collection initializers).

For example:

var d = new Dictionary<string, int>

{

["foo"] = 34, ["foo"] = 42,

}; // does not throw, second value overwrites the first one

versus:

var d = new Dictionary<string, int>

{

{"foo", 34 },

{"foo", 42 },

}; // run-time ArgumentException: An item with the same key has already been added.

Section 72.9: Improved overload resolution

Following snippet shows an example of passing a method group (as opposed to a lambda) when a delegate is expected. Overload resolution will now resolve this instead of raising an ambiguous overload error due to the ability of C# 6 to check the return type of the method that was passed.

using System; public class Program

{

public static void Main()

{

Overloaded(DoSomething);

}

static void Overloaded(Action action)

{

Console.WriteLine("overload with action called");

}

static void Overloaded(Func<int> function)

{

Console.WriteLine("overload with Func<int> called");

}

static int DoSomething()

{

Console.WriteLine(0); return 0;

}

}

Results:

Version = 6.0

GoalKicker.com – C# Notes for Professionals

435

Output

overload with Func<int> called

View Demo

Version = 5.0

Error

error CS0121: The call is ambiguous between the following methods or properties: 'Program.Overloaded(System.Action)' and 'Program.Overloaded(System.Func)'

C# 6 can also handle well the following case of exact matching for lambda expressions which would have resulted in an error in C# 5.

using System;

class Program

{

static void Foo(Func<Func<long>> func) {} static void Foo(Func<Func<int>> func) {}

static void Main()

{

Foo(() => () => 7);

}

}

Section 72.10: Await in catch and finally

It is possible to use await expression to apply await operator to Tasks or Task(Of TResult) in the catch and finally blocks in C#6.

It was not possible to use the await expression in the catch and finally blocks in earlier versions due to compiler limitations. C#6 makes awaiting async tasks a lot easier by allowing the await expression.

try

{

//since C#5

await service.InitializeAsync();

}

catch (Exception e)

{

//since C#6

await logger.LogAsync(e);

}

finally

{

//since C#6

await service.CloseAsync();

}

It was required in C# 5 to use a bool or declare an Exception outside the try catch to perform async operations.

GoalKicker.com – C# Notes for Professionals

436