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

case 6: case 7: case 8:

Console.WriteLine("Summer"); break;

case 9: case 10: case 11:

Console.WriteLine("Autumn"); break;

default:

Console.WriteLine("Incorrect month index"); break;

}

A case can only be labeled by a value known at compile time (e.g. 1, "str", Enum.A), so a variable isn't a valid case label, but a const or an Enum value is (as well as any literal value).

Section 52.37: var

An implicitly-typed local variable that is strongly typed just as if the user had declared the type. Unlike other variable declarations, the compiler determines the type of variable that this represents based on the value that is assigned to it.

var i = 10; // implicitly typed, the compiler must determine what type of variable this is int i = 10; // explicitly typed, the type of variable is explicitly stated to the compiler

// Note that these both represent the same type of variable (int) with the same value (10).

Unlike other types of variables, variable definitions with this keyword need to be initialized when declared. This is due to the var keyword representing an implicitly-typed variable.

var i; i = 10;

// This code will not run as it is not initialized upon declaration.

The var keyword can also be used to create new datatypes on the fly. These new datatypes are known as anonymous types. They are quite useful, as they allow a user to define a set of properties without having to explicitly declare any kind of object type first.

Plain anonymous type

var a = new { number = 1, text = "hi" };

LINQ query that returns an anonymous type

public class Dog

{

public string Name { get; set; } public int Age { get; set; }

}

public class DogWithBreed

{

public Dog Dog { get; set; }

public string BreedName { get; set; }

GoalKicker.com – C# Notes for Professionals

258

}

public void GetDogsWithBreedNames()

{

var db = new DogDataContext(ConnectString); var result = from d in db.Dogs

join b in db.Breeds on d.BreedId equals b.BreedId select new

{

DogName = d.Name, BreedName = b.BreedName

};

DoStuff(result);

}

You can use var keyword in foreach statement

public bool hasItemInList(List<String> list, string stringToSearch)

{

foreach(var item in list)

{

if( ( (string)item ).equals(stringToSearch) ) return true;

}

return false;

}

Section 52.38: when

The when is a keyword added in C# 6, and it is used for exception filtering.

Before the introduction of the when keyword, you could have had one catch clause for each type of exception; with the addition of the keyword, a more fine-grained control is now possible.

A when expression is attached to a catch branch, and only if the when condition is true, the catch clause will be executed. It is possible to have several catch clauses with the same exception class types, and di erent when conditions.

private void CatchException(Action action)

{

try

{

action.Invoke();

}

// exception filter

catch (Exception ex) when (ex.Message.Contains("when"))

{

Console.WriteLine("Caught an exception with when");

}

catch (Exception ex)

{

Console.WriteLine("Caught an exception without when");

}

}

GoalKicker.com – C# Notes for Professionals

259

private void Method1() { throw new Exception("message for exception with when"); } private void Method2() { throw new Exception("message for general exception"); }

CatchException(Method1);

CatchException(Method2);

Section 52.39: lock

lock provides thread-safety for a block of code, so that it can be accessed by only one thread within the same process. Example:

private static object _lockObj = new object(); static void Main(string[] args)

{

Task.Run(() => TaskWork()); Task.Run(() => TaskWork()); Task.Run(() => TaskWork());

Console.ReadKey();

}

private static void TaskWork()

{

lock(_lockObj)

{

Console.WriteLine("Entered");

Task.Delay(3000);

Console.WriteLine("Done Delaying");

// Access shared resources safely

Console.WriteLine("Leaving");

}

}

Output:

Entered

Done Delaying

Leaving

Entered

Done Delaying

Leaving

Entered

Done Delaying

Leaving

Use cases:

Whenever you have a block of code that might produce side-e ects if executed by multiple threads at the same time. The lock keyword along with a shared synchronization object (_objLock in the example) can be used to prevent that.

Note that _objLock can't be null and multiple threads executing the code must use the same object instance (either by making it a static field, or by using the same class instance for both threads)

From the compiler side, the lock keyword is a syntactic sugar that is replaced by Monitor.Enter(_lockObj); and

GoalKicker.com – C# Notes for Professionals

260

Monitor.Exit(_lockObj);. So if you replace the lock by surrounding the block of code with these two methods, you would get the same results. You can see actual code in Syntactic sugar in C# - lock example

Section 52.40: uint

An unsigned integer, or uint, is a numeric datatype that only can hold positive integers. Like it's name suggests, it represents an unsigned 32-bit integer. The uint keyword itself is an alias for the Common Type System type System.UInt32. This datatype is present in mscorlib.dll, which is implicitly referenced by every C# project when you create them. It occupies four bytes of memory space.

Unsigned integers can hold any value from 0 to 4,294,967,295.

Examples on how and now not to declare unsigned integers

uint i = 425697; // Valid expression, explicitly stated to compiler

var i1 = 789247U; // Valid expression, suffix allows compiler to determine datatype uint x = 3.0; // Error, there is no implicit conversion

Please note: According to Microsoft, it is recommended to use the int datatype wherever possible as the uint datatype is not CLS-compliant.

Section 52.41: if, if...else, if... else if

The if statement is used to control the flow of the program. An if statement identifies which statement to run based on the value of a Boolean expression.

For a single statement, the braces{} are optional but recommended.

int a = 4; if(a % 2 == 0)

{

Console.WriteLine("a contains an even number");

}

// output: "a contains an even number"

The if can also have an else clause, that will be executed in case the condition evaluates to false:

int a = 5; if(a % 2 == 0)

{

Console.WriteLine("a contains an even number");

}

else

{

Console.WriteLine("a contains an odd number");

}

// output: "a contains an odd number"

The if...else if construct lets you specify multiple conditions:

int a = 9; if(a % 2 == 0)

{

Console.WriteLine("a contains an even number");

}

else if(a % 3 == 0)

GoalKicker.com – C# Notes for Professionals

261