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

value++;

}

void SetByOut(out int value)

{

value = 34;

}

Live Demo on .NET Fiddle

The following does not compile, because out parameters must have a value assigned before the method returns (it would compile using ref instead):

void PrintByOut(out int value)

{

Console.WriteLine("Hello!");

}

using out keyword as Generic Modifier

out keyword can also be used in generic type parameters when defining generic interfaces and delegates. In this case, the out keyword specifies that the type parameter is covariant.

Covariance enables you to use a more derived type than that specified by the generic parameter. This allows for implicit conversion of classes that implement variant interfaces and implicit conversion of delegate types. Covariance and contravariance are supported for reference types, but they are not supported for value types. - MSDN

//if we have an interface like this interface ICovariant<out R> { }

//and two variables like

ICovariant<Object> iobj = new Sample<Object>(); ICovariant<String> istr = new Sample<String>();

//then the following statement is valid

//without the out keyword this would have thrown error iobj = istr; // implicit conversion occurs here

Section 52.25: base

The base keyword is used to access members from a base class. It is commonly used to call base implementations of virtual methods, or to specify which base constructor should be called.

Choosing a constructor

public class Child : SomeBaseClass {

public Child() : base("some string for the base class")

{

}

}

public class SomeBaseClass { public SomeBaseClass()

{

// new Child() will not call this constructor, as it does not have a parameter

GoalKicker.com – C# Notes for Professionals

246

}

public SomeBaseClass(string message)

{

// new Child() will use this base constructor because of the specified parameter in Child's constructor

Console.WriteLine(message);

}

}

Calling base implementation of virtual method

public override void SomeVirtualMethod() {

// Do something, then call base implementation base.SomeVirtualMethod();

}

It is possible to use the base keyword to call a base implementation from any method. This ties the method call directly to the base implementation, which means that even if new child classes override a virtual method, the base implementation will still be called so this needs to be used with caution.

public class Parent

{

public virtual int VirtualMethod()

{

return 1;

}

}

public class Child : Parent

{

public override int VirtualMethod() { return 11;

}

public int NormalMethod()

{

return base.VirtualMethod();

}

public void CallMethods()

{

Assert.AreEqual(11, VirtualMethod());

Assert.AreEqual(1, NormalMethod()); Assert.AreEqual(1, base.VirtualMethod());

}

}

public class GrandChild : Child

{

public override int VirtualMethod()

{

return 21;

}

public void CallAgain()

{

Assert.AreEqual(21, VirtualMethod()); Assert.AreEqual(11, base.VirtualMethod());

GoalKicker.com – C# Notes for Professionals

247

//Notice that the call to NormalMethod below still returns the value

//from the extreme base class even though the method has been overridden

//in the child class.

Assert.AreEqual(1, NormalMethod());

}

}

Section 52.26: float, double, decimal

float

float is an alias to the .NET datatype System.Single. It allows IEEE 754 single-precision floating point numbers to be stored. This data type is present in mscorlib.dll which is implicitly referenced by every C# project when you create them.

Approximate range: -3.4 × 1038 to 3.4 × 1038

Decimal precision: 6-9 significant digits

Notation:

float f = 0.1259;

var f1 = 0.7895f; // f is literal suffix to represent float values

It should be noted that the float type often results in significant rounding errors. In applications where precision is important, other data types should be considered.

double

double is an alias to the .NET datatype System.Double. It represents a double-precision 64-bit floating-point number. This datatype is present in mscorlib.dll which is implicitly referenced in any C# project.

Range: ±5.0 × 10−324 to ±1.7 × 10308

Decimal precision: 15-16 significant digits

Notation:

double distance = 200.34; // a double value

double salary = 245; // an integer implicitly type-casted to double value var marks = 123.764D; // D is literal suffix to represent double values

decimal

decimal is an alias to the .NET datatype System.Decimal. It represents a keyword indicates a 128-bit data type. Compared to floating-point types, the decimal type has more precision and a smaller range, which makes it appropriate for financial and monetary calculations. This datatype is present in mscorlib.dll which is implicitly referenced in any C# project.

Range: -7.9 × 1028 to 7.9 × 1028

Decimal precision: 28-29 significant digits

GoalKicker.com – C# Notes for Professionals

248

Notation:

decimal payable = 152.25m; // a decimal value

var marks = 754.24m; // m is literal suffix to represent decimal values

Section 52.27: operator

Most of the built-in operators (including conversion operators) can be overloaded by using the operator keyword along with the public and static modifiers.

The operators comes in three forms: unary operators, binary operators and conversion operators.

Unary and binary operators requires at least one parameter of same type as the containing type, and some requires a complementary matching operator.

Conversion operators must convert to or from the enclosing type.

public struct Vector32

{

public Vector32(int x, int y)

{

X = x; Y = y;

}

public int X { get; } public int Y { get; }

public static bool operator ==(Vector32 left, Vector32 right) => left.X == right.X && left.Y == right.Y;

public static bool operator !=(Vector32 left, Vector32 right) => !(left == right);

public static Vector32 operator +(Vector32 left, Vector32 right) => new Vector32(left.X + right.X, left.Y + right.Y);

public static Vector32 operator +(Vector32 left, int right) => new Vector32(left.X + right, left.Y + right);

public static Vector32 operator +(int left, Vector32 right) => right + left;

public static Vector32 operator -(Vector32 left, Vector32 right) => new Vector32(left.X - right.X, left.Y - right.Y);

public static Vector32 operator -(Vector32 left, int right) => new Vector32(left.X - right, left.Y - right);

public static Vector32 operator -(int left, Vector32 right) => right - left;

public static implicit operator Vector64(Vector32 vector) => new Vector64(vector.X, vector.Y);

public override string ToString() => $"{{{X}, {Y}}}";

}

GoalKicker.com – C# Notes for Professionals

249