C# – Other Operators

Other Operators

Most Common Operators
Equality and Comparison Operators

== : test for equality

!= : test for inequality

Conditional Operators:

&& : AND

|| : OR

Conditional operator (ternary operator)

Takes three operands q? a: b

The compound assignment operators are syntactic shortcuts that combine assignment
with another operator.
For example:

x *= 2 // equivalent to x = x * 2
x <<= 1 // equivalent to x = x << 1

Multiplicative Operators
x * y – multiplication.

x / y – division. If the operands are integers, the result is an integer truncated toward zero (for example, -7 / 2 is -3).

x % y – modulus. If the operands are integers, this returns the remainder of dividing x by y. If q = x / y and r = x % y, then x = q * y + r.
Additive Operators
x + y – addition for numeric and concatenation for string
x – y – subtraction for numeric

Shift Operators

x << y – shift bits left and fill with zero on the right.

x >> y – shift bits right. If the left operand is int or long, then left bits are filled with the sign bit. If the left operand is uint or ulong, then left bits are filled with zero.
Relational and Type-testing Operators

x < y – less than (true if x is less than y). x > y – greater than (true if x is greater than y).

x <= y – less than or equal to. x >= y – greater than or equal to.

is – type compatibility. Returns true if the evaluated left operand can be cast to the type specified in the right operand (a static type).

as – type conversion. Returns the left operand cast to the type specified by the right operand (a static type), but as returns null where (T)x would throw an exception.
Equality Operators

x == y – equality. By default, for reference types other than string, this returns reference equality (identity test). However, types can overload ==, so if your intent is to test identity, it is best to use the ReferenceEquals method on object.

x != y – not equal. See comment for ==. If a type overloads ==, then it must overload !=.

Logical AND Operator

x & y – logical or bitwise AND. Use with integer types and enum types is generally allowed.

Logical XOR Operator

x ^ y – logical or bitwise XOR. You can generally use this with integer types and enum types.

Logical OR Operator

x | y – logical or bitwise OR. Use with integer types and enum types is generally allowed.

Conditional AND Operator

x && y – logical AND. If the first operand is false, then C# does not evaluate the second operand.

Conditional OR Operator

x || y – logical OR. If the first operand is true, then C# does not evaluate the second operand.

Null-coalescing Operator

x ?? y – returns x if it is non-null; otherwise, returns y.

Conditional Operator

t ? x : y – if test t is true, then evaluate and return x; otherwise, evaluate and return y.

Assignment and Lambda Operators

x = y – assignment.

x += y – increment. Add the value of y to the value of x, store the result in x, and return the new value. If x designates an event, then y must be an appropriate function that C# adds as an event handler.

x -= y – decrement. Subtract the value of y from the value of x, store the result in x, and return the new value. If x designates an event, then y must be an appropriate function that C# removes as an event handler

x *= y – multiplication assignment. Multiply the value of y to the value of x, store the result in x, and return the new value.

x /= y – division assignment. Divide the value of x by the value of y, store the result in x, and return the new value.

x %= y – modulus assignment. Divide the value of x by the value of y, store the remainder in x, and return the new value.

x &= y – AND assignment. AND the value of y with the value of x, store the result in x, and return the new value.

x |= y – OR assignment. OR the value of y with the value of x, store the result in x, and return the new value.

x ^= y – XOR assignment. XOR the value of y with the value of x, store the result in x, and return the new value.

x <<= y – left-shift assignment. Shift the value of x left by y places, store the result in x, and return the new value. x >>= y – right-shift assignment. Shift the value of x right by y places, store the result in x, and return the new value.

=> – lambda declaration.

C# Unary Operators

Unary Operators

These operators have higher precedence than multiplicative operators and lower precedence than the primary operators.
+x
Functions as unary or binary as addition if it is numeric or concatenation if one of the value is string
-x
Performs numeric negation.
!x
Logical negation operator
~x
Bitwise complement.
await (Asynchronous method)
Awaits a Task. It iserts a sustension point to wait for a task to complete
&x – address of
Performs either unary or binary
*x – dereferencing
Works as a multiplication operator or dereference operator

C# Primary Operators

Operators

There are many different kinds of operators defined in C#. The operators can also be overloaded to change their meaning when applied to user-defined type.

Most common operators are (==, !=, <, >, &, |) and generally used with enumeration types.

Primary Operators

These are the highest precedence operators.
(Dot).Operator (x.y)

Composed of 2 primary expressions: member-lookup and method call. It is used for member access such as access specific method within the framework.

-- Accessing Console class in System namespace
System.Console.WriteLine("Hello World");

class Simple
{
	public int a;
	public void b() {}
}

--Initiate
Simple s = new Simple();

-- Accessing the members
s.a = 6; --asign to field a
s.b(); -- invoke member function b;

Null-conditional Operators (x?.y)
Returns null if the left-hand operand is null. It tests null before performing member access. In a chain conditional operation if operation returns null then rest execution stops. Null-conditional operator is useful when invoking delegates in a thread-safe with less code.

-- int? length - can be null or number
-- return null if customers is null or access the Length property
int? length = customers?.Length; 

-- return null if array is empty or access the array objects
Customer first = customer?[0]

-- return null if customers, first customer or Orders is null
int? count = customers?[0]?.Orders?.Count();

-- operations with lower precedence will continue to operate
A?.B?.C?[0] ?? E
A?.B?.C?[0] == E

-- using with thread
PropertyChanged?.Invoke(e);

Null-conditional Index Access (x?[y])

Returns null if the left-hand operand is null

Customer first = customers?[0];  -- null if customers is null 

Function Invocation f(x)
It is use to specify the order of operation. It cannot be overloaded.
1. Specifiy casts or type conversion

double x = 23.6;
int a;
a = (int)x;

2. Invoke methods or delegates
TestMethod();

Aggregate Object Indexing a[x]
Used for arrays, indexers and attributes or with pointers. Out of range exception if array is out of range.

int[] array;  -- array of int
array = new int[50] -- array for 50 element
--access array element
array[4];

Square brackets are also used to specify Attributes:

// using System.Diagnostics;
[Conditional("DEBUG")] 
void TraceMethod() {}

Postfix Increment (x++)

Returns the value of x by incrementing its operand by 1. It can appear before or after the variable.
prefix increment – result return after increment
postfix increment – result return before increment

double x = 2.5;
Console.WriteLine(++x); -- 3.5
x = 1.5;
Console.WriteLine(x++); -- 1.5
Console.WriteLine(x); -- 2.5

Postfix Decrement (x–)
Returns the decrement value by the operand. Can appear before or after the variable.

double x = 2.5;
Console.WriteLine(--x); -- 1.5
x = 1.5;
Console.WriteLine(x--); --1.5
Console.WriteLine(x); -- 0.5

Type Instantiation (new)
Create object and invoke constructors also create instances of anonymous types. It can be used to invoke the default constructor for value types. Cannot be overloaded. Remember not to declare default constructor for struct because every value type has a public constructor.

-- Class
Class1 obj = new Class1();

-- anonymous object
var query = from cust in customers  
            select new { Name = cust.Name, Address = cust.PrimaryAddress };  

-- value types
int i = new int();  

typeof()
Returns the System.Type object for a particular object. Can be used with open generics types.

System.Type type = typeof(int);  

For run-time expression

int i = 0;  
System.Type type = i.GetType(); 

int radius = 3;
        Console.WriteLine("Area = {0}", radius * radius * Math.PI);
        Console.WriteLine("The type is {0}",
                          (radius * radius * Math.PI).GetType()

-- generic example
string s = method.ReturnType.GetInterface  
    (typeof(System.Collections.Generic.IEnumerable<>).FullName);  


public class Program
    {
        public int sampleMember;
        public void SampleMethod() {}
        
        public static void Main(string[] args)
        {

        Type t = typeof(Program);
      // Alternatively, you could use
      // ExampleClass obj = new ExampleClass();
      // Type t = obj.GetType();

      Console.WriteLine("Methods:");
      System.Reflection.MethodInfo[] methodInfo = t.GetMethods();

      foreach (System.Reflection.MethodInfo mInfo in methodInfo)
         Console.WriteLine(mInfo.ToString());

      Console.WriteLine("Members:");
      System.Reflection.MemberInfo[] memberInfo = t.GetMembers();

      foreach (System.Reflection.MemberInfo mInfo in memberInfo)
         Console.WriteLine(mInfo.ToString());     
            
        
            
        }
        
 
    }

Checked
Enables overflow checking for integer operations and conversions

        int ten = 10;
        int i2 = 2147483647 + ten;
        Console.WriteLine(i2);
        Console.WriteLine(checked(2147483647 + ten));    
        
        checked
        {
            int i3 = 2147483647 + ten;
            Console.WriteLine(i3);
        } 

Unchecked
Disables overflow checking for integer operations. This is the default compiler behavior.

unchecked
{
    int1 = 2147483647 + 10;
}
int1 = unchecked(ConstantMax + 10);

Default Value Expression
Produces the default value of type T, null for references, 0 for numeric types.

var s = default(string);
var d = default(dynamic);
var i = default(int);
var n = default(int?); // n is a Nullable int where HasValue is false.

It can be applied in the following places:
– Variable initializer
– Variable assignment
– Declaring the default value for an optional parameter
– Providing the value for a method call argument
– Return statement (or expression in an expression bodied member)
Delegate (Anonymous Methods)
Declares and returns a delegate instance.

// Create a delegate.
delegate void Del(int x);

// Instantiate the delegate using an anonymous method.
Del d = delegate(int k) { /* ... */ };

It is an error to have jump statements such as continue or break.
sizeof
Returns the size in bytes for an unmanaged type such as enum, pointer,user-defined structs.
-> Pointer
Pointer dereferencing combined with member access.Used in unsafe environment.