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

public T GetResourceOrDefault<T>(string resourceName)

{

if (ResourceExists(resourceName))

{

return (T)GetResource(resourceName);

}

else

{

return default(T);

}

}

Section 52.14: sealed

When applied to a class, the sealed modifier prevents other classes from inheriting from it.

class A { }

sealed class B : A { }

class C : B { } //error : Cannot derive from the sealed class

When applied to a virtual method (or virtual property), the sealed modifier prevents this method (property) from

being overridden in derived classes.

public class A

{

public sealed override string ToString() // Virtual method inherited from class Object

{

return "Do not override me!";

}

}

public class B: A

{

public override string ToString() // Compile time error

{

return "An attempt to override";

}

}

Section 52.15: is

Checks if an object is compatible with a given type, i.e. if an object is an instance of the BaseInterface type, or a type that derives from BaseInterface:

interface BaseInterface {}

class BaseClass : BaseInterface {} class DerivedClass : BaseClass {}

var d = new DerivedClass();

 

Console.WriteLine(d is DerivedClass);

// True

Console.WriteLine(d is BaseClass);

// True

Console.WriteLine(d is BaseInterface);

// True

Console.WriteLine(d is object);

// True

Console.WriteLine(d is string);

// False

var b = new BaseClass();

 

Console.WriteLine(b is DerivedClass);

// False

Console.WriteLine(b is BaseClass);

// True

GoalKicker.com – C# Notes for Professionals

238

Console.WriteLine(b is

BaseInterface); //

True

Console.WriteLine(b

is

object);

//

True

Console.WriteLine(b

is

string);

//

False

 

 

 

 

 

If the intent of the cast is to use the object, it is best practice to use the as keyword'

interface BaseInterface {}

class BaseClass : BaseInterface {} class DerivedClass : BaseClass {}

var d = new DerivedClass();

 

 

 

 

 

Console.WriteLine(d

is

DerivedClass);

//

True -

valid use

of

'is'

Console.WriteLine(d

is

BaseClass);

//

True -

valid use

of

'is'

if(d is BaseClass){

var castedD = (BaseClass)d;

castedD.Method(); // valid, but not best practice

}

var asD = d as BaseClass;

if(asD!=null){

asD.Method(); //preferred method since you incur only one unboxing penalty

}

But, from C# 7 pattern matching feature extends the is operator to check for a type and declare a new variable at

the same time. Same code part with C# 7 :

Version ≥ 7.0

if(d is BaseClass asD ){ asD.Method();

}

Section 52.16: this

The this keyword refers to the current instance of class(object). That way two variables with the same name, one at the class-level (a field) and one being a parameter (or local variable) of a method, can be distinguished.

public MyClass { int a;

void set_a(int a)

{

//this.a refers to the variable defined outside of the method, //while a refers to the passed parameter.

this.a = a;

}

}

Other usages of the keyword are chaining non-static constructor overloads:

public MyClass(int arg) : this(arg, null)

{

}

and writing indexers:

public string this[int idx1, string idx2]

GoalKicker.com – C# Notes for Professionals

239

{

get { /* ... */ } set { /* ... */ }

}

and declaring extension methods:

public static int Count<TItem>(this IEnumerable<TItem> source)

{

// ...

}

If there is no conflict with a local variable or parameter, it is a matter of style whether to use this or not, so this.MemberOfType and MemberOfType would be equivalent in that case. Also see base keyword.

Note that if an extension method is to be called on the current instance, this is required. For example if your are inside a non-static method of a class which implements IEnumerable<> and you want to call the extension Count from before, you must use:

this.Count() // works like StaticClassForExtensionMethod.Count(this)

and this cannot be omitted there.

Section 52.17: readonly

The readonly keyword is a field modifier. When a field declaration includes a readonly modifier, assignments to that field can only occur as part of the declaration or in a constructor in the same class.

The readonly keyword is di erent from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have di erent values depending on the constructor used.

The readonly keyword is often used when injecting dependencies.

class Person

{

readonly string _name;

readonly string _surname = "Surname";

Person(string name)

{

_name = name;

}

void ChangeName()

{

_name = "another name"; // Compile error _surname = "another surname"; // Compile error

}

}

Note: Declaring a field readonly does not imply immutability. If the field is a reference type then the content of the object can be changed. Readonly is typically used to prevent having the object being overwritten and assigned only during instantiation of that object.

GoalKicker.com – C# Notes for Professionals

240

Note: Inside the constructor a readonly field can be reassigned

public class Car

{

public double Speed {get; set;}

}

//In code

private readonly Car car = new Car();

private void SomeMethod()

{

car.Speed = 100;

}

Section 52.18: typeof

Returns the Type of an object, without the need to instantiate it.

Type type = typeof(string);

Console.WriteLine(type.FullName); //System.String

Console.WriteLine("Hello".GetType() == type); //True

Console.WriteLine("Hello".GetType() == typeof(string)); //True

Section 52.19: foreach

foreach is used to iterate over the elements of an array or the items within a collection which implements

IEnumerable .

var lines = new string[] { "Hello world!",

"How are you doing today?", "Goodbye"

};

foreach (string line in lines)

{

Console.WriteLine(line);

}

This will output

"Hello world!"

"How are you doing today?" "Goodbye"

Live Demo on .NET Fiddle

You can exit the foreach loop at any point by using the break keyword or move on to the next iteration using the continue keyword.

var numbers = new int[] {1, 2, 3, 4, 5, 6};

foreach (var number in numbers)

GoalKicker.com – C# Notes for Professionals

241