Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharpNotesForProfessionals.pdf
Скачиваний:
57
Добавлен:
20.05.2023
Размер:
6.12 Mб
Скачать
Console.WriteLine("a contains an odd number that is a multiple of 3");

{

}

else

{

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

}

// output: "a contains an odd number that is a multiple of 3"

Important to note that if a condition is met in the above example , the control skips other tests and jumps to the end of that particular if else construct.So, the order of tests is important if you are using if .. else if construct

C# Boolean expressions use short-circuit evaluation. This is important in cases where evaluating conditions may have side e ects:

if (someBooleanMethodWithSideEffects() && someOtherBooleanMethodWithSideEffects()) {

//...

}

There's no guarantee that someOtherBooleanMethodWithSideEffects will actually run.

It's also important in cases where earlier conditions ensure that it's "safe" to evaluate later ones. For example:

if (someCollection != null && someCollection.Count > 0) {

// ..

}

The order is very important in this case because, if we reverse the order:

if (someCollection.Count > 0 && someCollection != null) {

it will throw a NullReferenceException if someCollection is null.

Section 52.42: static

The static modifier is used to declare a static member, which does not need to be instantiated in order to be accessed, but instead is accessed simply through its name, i.e. DateTime.Now.

static can be used with classes, fields, methods, properties, operators, events, and constructors.

While an instance of a class contains a separate copy of all instance fields of the class, there is only one copy of each static field.

class A

{

static public int count = 0;

public A()

{

count++;

}

}

class Program

{

static void Main(string[] args)

GoalKicker.com – C# Notes for Professionals

262

{

A a = new A(); A b = new A(); A c = new A();

Console.WriteLine(A.count); // 3

}

}

count equals to the total number of instances of A class.

The static modifier can also be used to declare a static constructor for a class, to initialize static data or run code that only needs to be called once. Static constructors are called before the class is referenced for the first time.

class A

{

static public DateTime InitializationTime;

// Static constructor static A()

{

InitializationTime = DateTime.Now;

// Guaranteed to only run once

Console.WriteLine(InitializationTime.ToString());

}

}

A static class is marked with the static keyword, and can be used as a beneficial container for a set of methods that work on parameters, but don't necessarily require being tied to an instance. Because of the static nature of the class, it cannot be instantiated, but it can contain a static constructor. Some features of a static class include:

Can't be inherited

Can't inherit from anything other than Object

Can contain a static constructor but not an instance constructor

Can only contain static members

Is sealed

The compiler is also friendly and will let the developer know if any instance members exist within the class. An example would be a static class that converts between US and Canadian metrics:

static class ConversionHelper {

private static double oneGallonPerLitreRate = 0.264172;

public static double litreToGallonConversion(int litres) { return litres * oneGallonPerLitreRate;

}

}

When classes are declared static:

public static class Functions

{

public static int Double(int value)

{

return value + value;

}

GoalKicker.com – C# Notes for Professionals

263

}

all function, properties or members within the class also need to be declared static. No instance of the class can be created. In essence a static class allows you to create bundles of functions that are grouped together logically.

Since C#6 static can also be used alongside using to import static members and methods. They can be used then without class name.

Old way, without using static:

using System;

public class ConsoleApplication

{

public static void Main()

{

Console.WriteLine("Hello World!"); //Writeline is method belonging to static class Console

}

}

Example with using static

using static System.Console;

public class ConsoleApplication

{

public static void Main()

{

WriteLine("Hello World!"); //Writeline is method belonging to static class Console

}

}

Drawbacks

While static classes can be incredibly useful, they do come with their own caveats:

Once the static class has been called, the class is loaded into memory and cannot be run through the garbage collector until the AppDomain housing the static class is unloaded.

A static class cannot implement an interface.

Section 52.43: internal

The internal keyword is an access modifier for types and type members. Internal types or members are accessible only within files in the same assembly

usage:

public class BaseClass

{

// Only accessible within the same assembly internal static int x = 0;

}

The di erence between di erent access modifiers is clarified here

GoalKicker.com – C# Notes for Professionals

264

Access modifiers

public

The type or member can be accessed by any other code in the same assembly or another assembly that references it.

private

The type or member can only be accessed by code in the same class or struct.

protected

The type or member can only be accessed by code in the same class or struct, or in a derived class.

internal

The type or member can be accessed by any code in the same assembly, but not from another assembly.

protected internal

The type or member can be accessed by any code in the same assembly, or by any derived class in another assembly.

When no access modifier is set, a default access modifier is used. So there is always some form of access modifier even if it's not set.

Section 52.44: using

There are two types of using keyword usage, using statement and using directive:

1.using statement:

The using keyword ensures that objects that implement the IDisposable interface are properly disposed after usage. There is a separate topic for the using statement

2.using directive

The using directive has three usages, see the msdn page for the using directive. There is a separate topic for the using directive.

Section 52.45: where

where can serve two purposes in C#: type constraining in a generic argument, and filtering LINQ queries.

GoalKicker.com – C# Notes for Professionals

265

In a generic class, let's consider

public class Cup<T>

{

// ...

}

T is called a type parameter. The class definition can impose constraints on the actual types that can be supplied for T.

The following kinds of constraints can be applied:

value type

reference type

default constructor

inheritance and implementation

value type

In this case only structs (this includes 'primitive' data types such as int, boolean etc) can be supplied

public class Cup<T> where T : struct

{

// ...

}

reference type

In this case only class types can be supplied

public class Cup<T> where T : class

{

// ...

}

hybrid value/reference type

Occasionally it is desired to restrict type arguments to those available in a database, and these will usually map to value types and strings. As all type restrictions must be met, it is not possible to specify where T : struct or string (this is not valid syntax). A workaround is to restrict type arguments to IConvertible which has built in types of "... Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, and String." It is possible other objects will implement IConvertible, though this is rare in practice.

public class Cup<T> where T : IConvertible

{

// ...

}

default constructor

Only types that contain a default constructor will be allowed. This includes value types and classes that contain a default (parameterless) constructor

public class Cup<T> where T : new

{

// ...

GoalKicker.com – C# Notes for Professionals

266