C# Operators and Expressions
1. 🔴 What are checked and unchecked operations in C#?
In C#, checked and unchecked are keywords used to control how arithmetic overflow is handled for integral types.
Overflow occurs when the result of a calculation exceeds the range supported by its data type.
For example, the maximum value of int is 2,147,483,647.
1. checked Operation
The checked keyword detects arithmetic overflow and throws an OverflowException when an overflow occurs at runtime.
Example:
int number = int.MaxValue;
checked
{
int result = number + 1;
Console.WriteLine(result);
}
Output:
OverflowException
Explanation:
-
int.MaxValueis2,147,483,647. -
Adding
1exceeds the maximum value. -
checkeddetects the overflow. -
An
OverflowExceptionis thrown.
Execution Flow:
int.MaxValue = 2147483647
|
v
Add 1
|
v
Overflow Occurs
|
v
checked Operation
|
v
OverflowException
2. unchecked Operation
The unchecked keyword allows arithmetic overflow without throwing an exception for the affected integral operations.
The result wraps around according to the data type's range.
Example:
int number = int.MaxValue;
unchecked
{
int result = number + 1;
Console.WriteLine(result);
}
Output:
-2147483648
Explanation:
-
int.MaxValueis2,147,483,647. -
Adding
1exceeds the maximum value. -
uncheckeddoes not throw an overflow exception. -
The result wraps around to
int.MinValue.
Execution Flow:
int.MaxValue = 2147483647
|
v
Add 1
|
v
Overflow Occurs
|
v
unchecked Operation
|
v
Result = -2147483648
Difference Between checked and unchecked
|
|
|
|---|---|
|
Detects arithmetic overflow |
Allows arithmetic overflow |
|
Throws |
Does not throw for integral overflow |
|
Useful when overflow must be detected |
Useful when wraparound is intentional |
|
Example: Financial calculations |
Example: Certain bitwise algorithms |
Key Points
-
checkeddetects overflow and throws an exception. -
uncheckedallows integral overflow and wraps the result. -
Both can be used as blocks or expressions.
-
They primarily apply to integral arithmetic and conversions.
-
Runtime integral arithmetic is generally unchecked by default unless configured otherwise.
-
Constant expressions are checked by default at compile time.
-
For financial calculations,
decimalis generally preferred overdouble;checkeddoes not make floating-point arithmetic exact.
Interview Answer: checked detects arithmetic overflow and throws an OverflowException, whereas unchecked allows integral overflow without throwing an exception and produces a wrapped result.
2. 🟢 What is the difference between default, typeof, and nameof in C#?
In C#, default, typeof, and nameof are operators or expressions used to retrieve default values, type information, and names of program elements.
1. default Operator
The default operator returns the default value of a specified data type.
Example:
int number = default(int);
bool isActive = default(bool);
string? name = default(string);
Console.WriteLine(number); // 0
Console.WriteLine(isActive); // False
Console.WriteLine(name); // Empty line (null)
Common Default Values:
|
Data Type |
Default Value |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Modern C# Syntax:
int number = default;
bool isActive = default;
string? name = default;
Here, the compiler identifies the target type automatically.
2. typeof Operator
The typeof operator returns a System.Type object containing information about a specified type.
Example:
Type type = typeof(string);
Console.WriteLine(type.Name);
Console.WriteLine(type.FullName);
Output:
String
System.String
Explanation:
-
typeof(string)retrieves information about thestringtype. -
Namereturns the simple type name. -
FullNamereturns the namespace-qualified type name.
Real-Time Example:
Type type = typeof(Employee);
Console.WriteLine(type.Name);
Output:
Employee
typeof is commonly used in reflection, dependency registration, and attribute processing.
3. nameof Operator
The nameof operator returns the name of a variable, class, method, property, or other named program element as a string.
Example:
string employeeName = "John";
Console.WriteLine(nameof(employeeName));
Output:
employeeName
Explanation:
-
nameof(employeeName)returns the variable name. -
It does not return the variable's value.
-
The result is determined at compile time.
Another Example:
class Employee
{
public string Name { get; set; } = "";
}
Console.WriteLine(nameof(Employee));
Console.WriteLine(nameof(Employee.Name));
Output:
Employee
Name
Real-Time Example: Parameter Validation
nameof is useful when throwing exceptions.
public void SaveEmployee(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException(
"Employee name is required",
nameof(name));
}
}
Explanation:
-
nameof(name)returns"name". -
If the parameter is renamed during refactoring, the compiler uses the updated name.
-
This avoids hardcoding parameter names as strings.
Difference Between default, typeof, and nameof
|
Feature |
|
|
|
|---|---|---|---|
|
Purpose |
Gets default value |
Gets type information |
Gets element name |
|
Returns |
Value of specified type |
|
|
|
Example |
|
|
|
|
Result |
|
Type information for |
|
|
Common Usage |
Initialization |
Reflection |
Validation and exceptions |
Key Points
-
defaultreturns the default value of a data type. -
typeofreturns type metadata as aSystem.Typeobject. -
nameofreturns the name of a program element as a string. -
defaultis commonly used in initialization and generic programming. -
typeofis commonly used in reflection and dependency injection. -
nameofhelps avoid hardcoded strings and improves refactoring safety.
Interview Answer: default returns the default value of a type, typeof returns a System.Type object representing a type, and nameof returns the name of a program element as a string.
Quick Interview Revision
|
Concept |
Key Point |
|---|---|
|
|
Detects overflow and throws an exception |
|
|
Allows integral overflow without an exception |
|
|
|
|
|
|
|
|
Returns |
|
|
Returns |
|
|
Returns |
|
|
Returns |
Important Interview Tip: Remember these two differences: checked vs unchecked controls integral overflow behavior, while default, typeof, and nameof return a default value, type information, and a program element's name, respectively.