The ==, !=, <, >, <=, >=, is and as operators are called the relational and type-testing operators.

*relational-expression:shift-expressionrelational-expression < shift-expressionrelational-expression > shift-expressionrelational-expression <= shift-expressionrelational-expression >= shift-expressionrelational-expression is typerelational-expression as type*

*equality-expression:relational-expressionequality-expression == relational-expressionequality-expression != relational-expression*

The is operator is described in §7.9.10 and the as operator is described in §7.9.11.

The ==, !=, <, >, <= and >= operators are * comparison operators*. For an operation of the form x

The predefined comparison operators are described in the following sections. All predefined comparison operators return a result of type bool, as described in the following table.

| |

x == y | true if x is equal to y, false otherwise |

x != y | true if x is not equal to y, false otherwise |

x < y | true if x is less than y, false otherwise |

x > y | true if x is greater than y, false otherwise |

x <= y | true if x is less than or equal to y, false otherwise |

x >= y | true if x is greater than or equal to y, false otherwise |

### Integer comparison operators

The predefined integer comparison operators are:

bool operator ==(int x, int y);

bool operator ==(uint x, uint y);

bool operator ==(long x, long y);

bool operator ==(ulong x, ulong y);

bool operator !=(int x, int y);

bool operator !=(uint x, uint y);

bool operator !=(long x, long y);

bool operator !=(ulong x, ulong y);

bool operator <(int x, int y);

bool operator <(uint x, uint y);

bool operator <(long x, long y);

bool operator <(ulong x, ulong y);

bool operator >(int x, int y);

bool operator >(uint x, uint y);

bool operator >(long x, long y);

bool operator >(ulong x, ulong y);

bool operator <=(int x, int y);

bool operator <=(uint x, uint y);

bool operator <=(long x, long y);

bool operator <=(ulong x, ulong y);

bool operator >=(int x, int y);

bool operator >=(uint x, uint y);

bool operator >=(long x, long y);

bool operator >=(ulong x, ulong y);

Each of these operators compares the numeric values of the two integer operands and returns a bool value that indicates whether the particular relation is true or false.

### Floating-point comparison operators

The predefined floating-point comparison operators are:

bool operator ==(float x, float y);

bool operator ==(double x, double y);

bool operator !=(float x, float y);

bool operator !=(double x, double y);

bool operator <(float x, float y);

bool operator <(double x, double y);

bool operator >(float x, float y);

bool operator >(double x, double y);

bool operator <=(float x, float y);

bool operator <=(double x, double y);

bool operator >=(float x, float y);

bool operator >=(double x, double y);

The operators compare the operands according to the rules of the IEEE 754 standard:

If either operand is NaN, the result is false for all operators except !=, for which the result is true. For any two operands, x != y always produces the same result as !(x == y). However, when one or both operands are NaN, the <, >, <=, and >= operators

*do not*produce the same results as the logical negation of the opposite operator. For example, if either of x and y is NaN, then x < y is false, but !(x >= y) is true.When neither operand is NaN, the operators compare the values of the two floating-point operands with respect to the ordering

–∞ < –max < ... < –min < –0.0 == +0.0 < +min < ... < +max < +∞

where min and max are the smallest and largest positive finite values that can be represented in the given floating-point format. Notable effects of this ordering are:

Negative and positive zeros are considered equal.

A negative infinity is considered less than all other values, but equal to another negative infinity.

A positive infinity is considered greater than all other values, but equal to another positive infinity.

### Decimal comparison operators

The predefined decimal comparison operators are:

bool operator ==(decimal x, decimal y);

bool operator !=(decimal x, decimal y);

bool operator <(decimal x, decimal y);

bool operator >(decimal x, decimal y);

bool operator <=(decimal x, decimal y);

bool operator >=(decimal x, decimal y);

Each of these operators compares the numeric values of the two decimal operands and returns a bool value that indicates whether the particular relation is true or false. Each decimal comparison is equivalent to using the corresponding relational or equality operator of type System.Decimal.

### Boolean equality operators

The predefined boolean equality operators are:

bool operator ==(bool x, bool y);

bool operator !=(bool x, bool y);

The result of == is true if both x and y are true or if both x and y are false. Otherwise, the result is false.

The result of != is false if both x and y are true or if both x and y are false. Otherwise, the result is true. When the operands are of type bool, the != operator produces the same result as the ^ operator.

### Enumeration comparison operators

Every enumeration type implicitly provides the following predefined comparison operators:

bool operator ==(E x, E y);

bool operator !=(E x, E y);

bool operator <(E x, E y);

bool operator >(E x, E y);

bool operator <=(E x, E y);

bool operator >=(E x, E y);

The result of evaluating x *op* y, where x and y are expressions of an enumeration type E with an underlying type U, and *op* is one of the comparison operators, is exactly the same as evaluating ((U)x) *op* ((U)y). In other words, the enumeration type comparison operators simply compare the underlying integral values of the two operands.

### Reference type equality operators

The predefined reference type equality operators are:

bool operator ==(object x, object y);

bool operator !=(object x, object y);

The operators return the result of comparing the two references for equality or non-equality.

Since the predefined reference type equality operators accept operands of type object, they apply to all types that do not declare applicable operator == and operator != members. Conversely, any applicable user-defined equality operators effectively hide the predefined reference type equality operators.

The predefined reference type equality operators require one of the following:

Both operands are

*reference-type*values or the value null. Furthermore, a standard implicit conversion exists from the type of either operand to the type of the other operand.One operand is a value of type T where T is a

*type-parameter*and the other operand is the value null. Furthermore T does not have the value type constraint.

Unless one of these conditions are true, a compile-time error occurs. Notable implications of these rules are:

It is a compile-time error to use the predefined reference type equality operators to compare two references that are known to be different at compile-time. For example, if the compile-time types of the operands are two class types A and B, and if neither A nor B derives from the other, then it would be impossible for the two operands to reference the same object. Thus, the operation is considered a compile-time error.

The predefined reference type equality operators do not permit value type operands to be compared. Therefore, unless a struct type declares its own equality operators, it is not possible to compare values of that struct type.

The predefined reference type equality operators never cause boxing operations to occur for their operands. It would be meaningless to perform such boxing operations, since references to the newly allocated boxed instances would necessarily differ from all other references.

If an operand of a type parameter type T is compared to null, and the runtime type of T is a value type, the result of the comparison is false.

The following example checks whether an argument of an unconstrained type parameter type is null.

class C<T>

{

void F(T x) {

if (x == null) throw new ArgumentNullException();

...

}

}

The x == null construct is permitted even though T could represent a value type, and the result is simply defined to be false when T is a value type.

For an operation of the form x == y or x != y, if any applicable operator == or operator != exists, the operator overload resolution rules will select that operator instead of the predefined reference type equality operator. However, it is always possible to select the predefined reference type equality operator by explicitly casting one or both of the operands to type object. The example

using System;

class Test

{

static void Main() {

string s = "Test";

string t = string.Copy(s);

Console.WriteLine(s == t);

Console.WriteLine((object)s == t);

Console.WriteLine(s == (object)t);

Console.WriteLine((object)s == (object)t);

}

}

produces the output

True

False

False

False

The s and t variables refer to two distinct string instances containing the same characters. The first comparison outputs True because the predefined string equality operator is selected when both operands are of type string. The remaining comparisons all output False because the predefined reference type equality operator is selected when one or both of the operands are of type object.

Note that the above technique is not meaningful for value types. The example

class Test

{

static void Main() {

int i = 123;

int j = 123;

System.Console.WriteLine((object)i == (object)j);

}

}

outputs False because the casts create references to two separate instances of boxed int values.

### String equality operators

The predefined string equality operators are:

bool operator ==(string x, string y);

bool operator !=(string x, string y);

Two string values are considered equal when one of the following is true:

Both values are null.

Both values are non-null references to string instances that have identical lengths and identical characters in each character position.

The string equality operators compare string *values* rather than string *references*. When two separate string instances contain the exact same sequence of characters, the values of the strings are equal, but the references are different. As described in §7.9.6, the reference type equality operators can be used to compare string references instead of string values.

### Delegate equality operators

Every delegate type implicitly provides the following predefined comparison operators:

bool operator ==(System.Delegate x, System.Delegate y);

bool operator !=(System.Delegate x, System.Delegate y);

Two delegate instances are considered equal as follows:

If either of the delegate instances is null, they are equal if and only if both are null.

If the delegates have different runtime type they are never equal.

If both of the delegate instances have an invocation list , those instances are equal if and only if their invocation lists are the same length, and each entry in one’s invocation list is equal (as defined below) to the corresponding entry, in order, in the other’s invocation list.

The following rules govern the equality of invocation list entries:

If two invocation list entries both refer to the same static method then the entries are equal.

If two invocation list entries both refer to the same non-static method on the same target object (as defined by the reference equality operators) then the entries are equal.

Invocation list entries produced from evaluation of semantically identical

*anonymous-function-expression*s with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal.

### Equality operators and null

The == and != operators permit one operand to be a value of a nullable type and the other to be the null literal, even if no predefined or user-defined operator (in unlifted or lifted form) exists for the operation.

For an operation of one of the forms

x == null null == x x != null null != x

where x is an expression of a nullable type, if operator overload resolution fails to find an applicable operator, the result is instead computed from the HasValue property of x. Specifically, the first two forms are translated into !x.HasValue, and last two forms are translated into x.HasValue.

### The is operator

The is operator is used to dynamically check if the run-time type of an object is compatible with a given type. The result of the operation E is T, where E is an expression and T is a type, is a boolean value indicating whether E can successfully be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion. The operation is evaluated as follows, after type arguments have been substituted for all type parameters:

If E is an anonymous function, a compile time error occurs

If E is a method group or the null literal, of if the type of E is a reference type or a nullable type and the value of E is null, the result is false.

Otherwise, let D represent the dynamic type of E as follows:

If the type of E is a reference type, D is the run-time type of the instance reference by E.

If the type of E is a nullable type, D is the underlying type of that nullable type.

If the type of E is a non-nullable value type, D is the type of E.

The result of the operation depends on D and T as follows:

If T is a reference type, the result is true if D and T are the same type, if D is a reference type and an implicit reference conversion from D to T exists, or if D is a value type and a boxing conversion from D to T exists.

If T is a nullable type, the result is true if D is the underlying type of T.

If T is a non-nullable value type, the result is true if D and T are the same type.

Otherwise, the result is false.

Note that user defined conversions, are not considered by the is operator.

### The as operator

The as operator is used to explicitly convert a value to a given reference type or nullable type. Unlike a cast expression , the as operator never throws an exception. Instead, if the indicated conversion is not possible, the resulting value is null.

In an operation of the form E as T, E must be an expression and T must be a reference type, a type parameter known to be a reference type, or a nullable type. Furthermore, at least one of the following must be true, or otherwise a compile-time error occurs:

An identity , implicit reference , boxing , explicit reference , or unboxing conversion exists from the type of E to T.

The type of E or T is an open type.

E is the null literal.

The operation E as T produces the same result as

E is T ? (T)(E) : (T)null

except that E is only evaluated once. The compiler can be expected to optimize E as T to perform at most one dynamic type check as opposed to the two dynamic type checks implied by the expansion above.

Note that some conversions, such as user defined conversions, are not possible with the as operator and should instead be performed using cast expressions.

In the example

class X

{

public string F(object o) {

return o as string; // OK, string is a reference type

}

public T G<T>(object o) where T: Attribute {

return o as T; // Ok, T has a class constraint

}

public U H<U>(object o) {

return o as U; // Error, U is unconstrained

}

}

the type parameter T of G is known to be a reference type, because it has the class constraint. The type parameter U of H is not however; hence the use of the as operator in H is disallowed.

Content

License.

All information of this service is derived from the free sources and is provided solely in the form of quotations.
This service provides information and interfaces solely for the familiarization (not ownership) and under the "as is" condition.

Copyright 2016 © ELTASK.COM. All rights reserved.

Site is optimized for mobile devices.

Downloads: 1207 / . Delta: 0.02028 с

Site is optimized for mobile devices.

Downloads: 1207 / . Delta: 0.02028 с