C# Operators and Type Conversion – Detailed Explanation with Examples
C# provides different types of operators to perform arithmetic calculations, comparisons, logical operations, bitwise operations, and null handling.
This section covers six important C# interview questions with explanations, practical examples, comparisons, and key points.
1. What are the different types of operators in C#?
What is an operator?
An operator is a symbol or keyword used to perform an operation on one or more operands (variables or values).
Example:
int a = 10;
int b = 20;
int result = a + b;
Console.WriteLine(result); // 30
Here:
-
aandbare operands. -
+is an arithmetic operator. -
=is an assignment operator. -
resultstores the calculated value.
Types of operators in C#
|
Operator Type |
Operators |
Purpose |
|---|---|---|
|
Arithmetic |
|
Mathematical operations |
|
Relational |
|
Compare values |
|
Logical |
|
Combine or negate Boolean conditions |
|
Assignment |
|
Assign or update values |
|
Increment/Decrement |
|
Increase or decrease by one |
|
Bitwise |
|
Perform bit-level operations |
|
Shift |
|
Shift bits left or right |
|
Conditional |
|
Select a value based on a condition |
|
Null-coalescing |
|
Handle null values |
|
Null-conditional |
|
Safely access nullable references |
|
Type checking |
|
Check or work with types |
|
Other |
|
Object creation, type information, asynchronous operations |
A. Arithmetic Operators
Used to perform mathematical calculations.
int a = 10;
int b = 3;
Console.WriteLine(a + b); // 13
Console.WriteLine(a - b); // 7
Console.WriteLine(a * b); // 30
Console.WriteLine(a / b); // 3
Console.WriteLine(a % b); // 1
Important: When both operands are integers, division produces an integer result.
Console.WriteLine(10 / 3); // 3
Console.WriteLine(10.0 / 3); // 3.3333333333333335
B. Relational Operators
Used to compare two values. The result is a Boolean (true or false).
int a = 10;
int b = 20;
Console.WriteLine(a == b); // False
Console.WriteLine(a != b); // True
Console.WriteLine(a > b); // False
Console.WriteLine(a < b); // True
Console.WriteLine(a >= b); // False
Console.WriteLine(a <= b); // True
C. Logical Operators
Used to combine Boolean conditions.
int age = 25;
bool hasLicense = true;
if (age >= 18 && hasLicense)
{
Console.WriteLine("Eligible to drive");
}
D. Assignment Operators
int a = 10;
a += 5; // a = 15
a -= 3; // a = 12
a *= 2; // a = 24
a /= 4; // a = 6
a %= 4; // a = 2
E. Conditional (Ternary) Operator
The ternary operator is a shorter alternative to simple if-else assignments.
Syntax:
condition ? valueIfTrue : valueIfFalse;
Example:
int age = 20;
string result = age >= 18 ? "Adult" : "Minor";
Console.WriteLine(result); // Adult
Operator Classification Diagram
C# OPERATORS
|
+---------------+---------------+
| | |
Arithmetic Logical Comparison
| | |
+ - * / % && || ! == != > <
>= <=
|
+---------------+---------------+
| | |
Assignment Bitwise Conditional
| | |
= += -= & | ^ ~ ?:
|
+---------------+---------------+
| | |
Null Handling Increment Type Checking
| | |
?? ??= ?. ++ -- is as typeof
Key Points
-
Operators perform operations on operands.
-
Arithmetic operators perform mathematical calculations.
-
Relational operators return Boolean results.
-
Logical operators combine Boolean expressions.
-
Assignment operators modify variable values.
-
Operators have precedence and associativity rules that determine evaluation order.
2. What is the difference between && and &, and between || and |?
Logical vs Bitwise Operators
The main difference is short-circuit evaluation.
-
&&and||are conditional logical operators that support short-circuit evaluation. -
&and|can be used with Boolean values without short-circuiting, or with integral values for bitwise operations.
A. Difference between && and &
Both can perform logical AND when used with Boolean operands.
Using && – Short-Circuit AND
int a = 10;
int b = 20;
if (a > 20 && b > 10)
{
Console.WriteLine("Both conditions are true");
}
Execution Flow:
Condition 1: a > 20
|
v
False
|
v
Skip Condition 2
|
v
Overall Result: False
Because the first condition is false, C# does not evaluate the second condition.
Using & – Non-Short-Circuit AND
int a = 10;
int b = 20;
if (a > 20 & b > 10)
{
Console.WriteLine("Both conditions are true");
}
Execution Flow:
Condition 1: a > 20
|
v
False
|
v
Condition 2: b > 10
|
v
True
|
v
Overall Result: False
Both conditions are evaluated.
B. Difference between || and |
Using || – Short-Circuit OR
int a = 10;
int b = 20;
if (a == 10 || b == 30)
{
Console.WriteLine("At least one condition is true");
}
Execution Flow:
Condition 1: a == 10
|
v
True
|
v
Skip Condition 2
|
v
Overall Result: True
Because the first condition is true, the second condition is not evaluated.
Using | – Non-Short-Circuit OR
int a = 10;
int b = 20;
if (a == 10 | b == 30)
{
Console.WriteLine("At least one condition is true");
}
Both conditions are evaluated.
C. Practical Example – Preventing NullReferenceException
string? name = null;
if (name != null && name.Length > 5)
{
Console.WriteLine("Valid name");
}
This is safe because name.Length is not evaluated when name is null.
Now consider:
string? name = null;
if (name != null & name.Length > 5)
{
Console.WriteLine("Valid name");
}
This throws a NullReferenceException because & evaluates both operands.
Comparison Table
|
Feature |
|
|
|
|
|---|---|---|---|---|
|
Operation on |
AND |
AND |
OR |
OR |
|
Short-circuit |
Yes |
No |
Yes |
No |
|
Always evaluates right operand |
No |
Yes |
No |
Yes |
|
Bitwise operations on integers |
No |
Yes |
No |
Yes |
|
Typical usage |
Conditional AND |
Bitwise AND |
Conditional OR |
Bitwise OR |
Key Points
-
&&skips the second condition when the first is false. -
||skips the second condition when the first is true. -
&and|evaluate both Boolean operands. -
&and|also perform bitwise operations on integral types. -
Prefer
&&and||for normal conditional statements. -
Short-circuit evaluation is especially useful for null checks and avoiding unnecessary method calls.
3. What are the null-coalescing (??) and null-conditional (?.) operators?
Null Handling Operators in C#
Null-handling operators help prevent null-related errors and reduce repetitive null checks.
A. Null-Coalescing Operator (??)
The ?? operator returns the left-hand value if it is not null. Otherwise, it returns the right-hand value.
Syntax:
result = value ?? defaultValue;
Example:
string? name = null;
string result = name ?? "Guest";
Console.WriteLine(result);
Output:
Guest
How does it work?
name ?? "Guest"
|
v
Is name null?
/ \
Yes No
| |
v v
"Guest" name value
\ /
\ /
Result
Equivalent if-else:
string? name = null;
string result;
if (name != null)
{
result = name;
}
else
{
result = "Guest";
}
B. Null-Conditional Operator (?.)
The ?. operator safely accesses a member only when the object is not null.
Without ?.:
string? name = null;
Console.WriteLine(name.Length);
This throws a NullReferenceException.
With ?.:
string? name = null;
int? length = name?.Length;
Console.WriteLine(length); // No value (null)
How does it work?
name?.Length
|
v
Is name null?
/ \
Yes No
| |
v v
null name.Length
\ /
\ /
Result
C. Combining ?. and ??
This is a common interview question.
string? name = null;
int length = name?.Length ?? 0;
Console.WriteLine(length); // 0
Explanation:
-
name?.Lengthchecks whethernameis null. -
Since
nameis null, the expression produces null. -
?? 0replaces null with zero. -
The final result is
0.
D. Null-Coalescing Assignment (??=)
The ??= operator assigns a value only when the variable is null.
string? name = null;
name ??= "Guest";
Console.WriteLine(name); // Guest
If name already contains a value, it remains unchanged.
E. Real-World Example in ASP.NET Core
Suppose an API receives an optional search parameter.
public IActionResult GetProducts(string? search)
{
string searchText = search ?? "";
return Ok(searchText);
}
If search is null, an empty string is used.
Another example:
int totalItems = response?.Items?.Count ?? 0;
If response or Items is null, totalItems becomes zero.
Comparison Table
|
Operator |
Purpose |
Example |
|---|---|---|
|
|
Provides fallback value |
|
|
|
Safely accesses member |
|
|
|
Safely accesses element |
|
|
|
Assigns when null |
|
Note: items?[0] protects against a null collection, but does not prevent an index-out-of-range exception.
Key Points
-
??returns a fallback value when the left operand is null. -
?.prevents null dereferencing for the guarded access. -
??=assigns only when the existing value is null. -
?.can return a nullable result when accessing a value-type member. -
??and?.are frequently combined. -
These operators improve readability and reduce explicit null checks.
4. What is the difference between prefix and postfix increment operators?
Prefix (++a) vs Postfix (a++)
Both increment a variable by one, but they differ in when the incremented value is produced by the expression.
A. Prefix Increment (++a)
The variable is incremented first, and the updated value is used.
int a = 10;
int b = ++a;
Console.WriteLine(a); // 11
Console.WriteLine(b); // 11
Execution Flow:
Initial Value
a = 10
|
v
++a
|
v
Increment a
a = 11
|
v
Assign to b
b = 11
B. Postfix Increment (a++)
The original value is produced by the expression, and the variable is incremented.
int a = 10;
int b = a++;
Console.WriteLine(a); // 11
Console.WriteLine(b); // 10
Execution Flow:
Initial Value
a = 10
|
v
a++
|
v
Original Value = 10
|
v
Increment a to 11
|
v
Assign Original Value to b
b = 10
C. Comparison
|
Feature |
Prefix |
Postfix |
|---|---|---|
|
Increments variable |
Yes |
Yes |
|
Expression produces |
New value |
Original value |
|
Example initial value |
10 |
10 |
|
Final variable value |
11 |
11 |
|
Assigned expression value |
11 |
10 |
D. Important Interview Example
int a = 5;
int result = a++ + ++a;
Console.WriteLine(a);
Console.WriteLine(result);
Step-by-step execution:
Initial:
a = 5
Step 1:
a++ produces 5
a becomes 6
Step 2:
++a increments a to 7
++a produces 7
Step 3:
result = 5 + 7
Final:
a = 7
result = 12
Output:
7
12
C# evaluates these operands from left to right.
Although this is valid C#, combining multiple increments in one expression reduces readability and should generally be avoided.
E. Does prefix or postfix matter in a for loop?
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
for (int i = 0; i < 5; ++i)
{
Console.WriteLine(i);
}
Both loops produce:
0
1
2
3
4
Because the increment expression's result is discarded, both forms have the same observable behavior for a normal integer loop counter.
Key Points
-
Prefix increments first and produces the new value.
-
Postfix produces the old value while still incrementing the variable.
-
Both increase the variable by one.
-
The difference matters when the expression's value is used.
-
For ordinary integer
forloops, both forms behave equivalently. -
Avoid complicated expressions containing multiple increments.
5. What are bitwise and shift operators?
Bitwise Operators in C#
Bitwise operators perform operations directly on the binary representation of integral values.
They are commonly used in:
-
Flags and permissions
-
Low-level programming
-
Binary protocols
-
Hardware-related operations
-
Efficient bit manipulation
A. Bitwise AND (&)
Returns 1 only when both corresponding bits are 1.
int a = 5;
int b = 3;
Console.WriteLine(a & b); // 1
Binary Explanation:
Decimal Binary
------- ------
5 0101
3 0011
AND Operation:
0101
& 0011
------
0001 = 1
B. Bitwise OR (|)
Returns 1 when at least one corresponding bit is 1.
int a = 5;
int b = 3;
Console.WriteLine(a | b); // 7
0101
| 0011
------
0111 = 7
C. Bitwise XOR (^)
Returns 1 when the corresponding bits are different.
int a = 5;
int b = 3;
Console.WriteLine(a ^ b); // 6
0101
^ 0011
------
0110 = 6
D. Bitwise NOT (~)
Inverts every bit.
int a = 5;
Console.WriteLine(~a); // -6
Why is the result -6?
C# int uses a 32-bit signed representation.
5:
00000000 00000000 00000000 00000101
~5:
11111111 11111111 11111111 11111010
Signed Result: -6
For an integer x, the identity ~x == -x - 1 holds.
E. Shift Operators
Shift operators move bits left or right.
Left Shift (<<)
int a = 5;
Console.WriteLine(a << 1); // 10
Console.WriteLine(a << 2); // 20
Binary Explanation:
Original:
5 = 00000101
Left Shift by 1:
00001010 = 10
Left Shift by 2:
00010100 = 20
For suitable positive values without overflow, shifting left by one is equivalent to multiplying by two.
Right Shift (>>)
int a = 20;
Console.WriteLine(a >> 1); // 10
Console.WriteLine(a >> 2); // 5
Original:
20 = 00010100
Right Shift by 1:
00001010 = 10
Right Shift by 2:
00000101 = 5
For nonnegative integers, shifting right by one is equivalent to integer division by two.
Unsigned Right Shift (>>>)
C# 11 introduced the unsigned right-shift operator.
int a = -8;
Console.WriteLine(a >> 1); // -4
Console.WriteLine(a >>> 1); // 2147483644
>> preserves the sign for signed integers, while >>> fills the newly introduced high-order bits with zeros.
F. Real-World Example – User Permissions
Bitwise operators are useful when storing multiple permissions in a single value.
[Flags]
enum Permission
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
Permission userPermission =
Permission.Read | Permission.Write;
bool canWrite =
(userPermission & Permission.Write)
== Permission.Write;
Console.WriteLine(canWrite); // True
How it works:
Read = 001
Write = 010
Delete = 100
Read | Write
------------
001
| 010
-----
011
User Permissions = 011
Check Write:
011
& 010
-----
010
Result = Write Permission
Comparison Table
|
Operator |
Name |
Example |
Result |
|---|---|---|---|
|
|
Bitwise AND |
|
1 |
|
|
Bitwise OR |
|
7 |
|
|
Bitwise XOR |
|
6 |
|
|
Bitwise NOT |
|
-6 |
|
|
Left shift |
|
10 |
|
|
Right shift |
|
10 |
|
|
Unsigned right shift |
|
2147483644 |
Key Points
-
Bitwise operators manipulate individual bits.
-
&,|, and^compare corresponding bits. -
~inverts bits. -
<<shifts bits left. -
>>performs arithmetic right shift on signed integers. -
>>>performs unsigned right shift. -
Bitwise operators are particularly useful for permission flags and binary data.
6. What is the difference between Parse(), TryParse(), and Convert.ToInt32()?
String to Integer Conversion in C#
All three are commonly used to convert values into integers, but their handling of invalid values and nulls differs.
A. int.Parse()
Parse() converts a valid numeric string into an integer.
Example:
string value = "100";
int number = int.Parse(value);
Console.WriteLine(number); // 100
What happens with invalid input?
string value = "ABC";
int number = int.Parse(value);
This throws a FormatException.
If the input is null, int.Parse() throws an ArgumentNullException.
If the numeric value exceeds the int range, it throws an OverflowException.
When to use?
Use Parse() when the input is expected to be valid and invalid data should be treated as an error.
B. int.TryParse()
TryParse() attempts to convert a string into an integer without throwing an exception for ordinary conversion failures.
It returns:
-
truewhen conversion succeeds. -
falsewhen conversion fails.
Example:
string value = "100";
bool success = int.TryParse(value, out int number);
Console.WriteLine(success); // True
Console.WriteLine(number); // 100
Invalid Input:
string value = "ABC";
bool success = int.TryParse(value, out int number);
Console.WriteLine(success); // False
Console.WriteLine(number); // 0
How does it work?
Input: "100"
|
v
int.TryParse()
|
v
Valid Integer?
/ \
Yes No
| |
v v
Return true Return false
number = 100 number = 0
Practical Example:
Console.Write("Enter your age: ");
string? input = Console.ReadLine();
if (int.TryParse(input, out int age))
{
Console.WriteLine($"Your age is {age}");
}
else
{
Console.WriteLine("Invalid age");
}
This is suitable for user input because invalid text does not cause an ordinary conversion exception.
C. Convert.ToInt32()
Convert.ToInt32() converts supported values into a 32-bit integer.
It can accept strings, Boolean values, floating-point values, and other supported convertible types.
Example:
string value = "100";
int number = Convert.ToInt32(value);
Console.WriteLine(number); // 100