Module 1 · Foundations · Lesson 2 of 15
Core C# and CLR basics
Question 1. What is the difference between casting, conversion, and parsing?
Answer: Casting asks the compiler/runtime to treat a value as another compatible type. Conversion creates a value of another type. Parsing converts text into a typed value by interpreting the text.
object value = "hello";
string casted = (string)value; // cast
var amount = 12.7;
int converted = (int)amount; // conversion, loses .7
bool ok = int.TryParse("123", out int parsed); // parsing textInterview tip: Mention failure modes: invalid casts throw InvalidCastException; numeric conversions can lose precision; Parse throws; TryParse returns false.
Question 2. What is object casting and pattern matching?
Answer: Object casting converts a reference to a more specific or compatible type at runtime. Pattern matching with is is safer because it checks the type and declares a typed variable in one step.
object x = 10;
if (x is int y)
{
Console.WriteLine(y + 1);
}var text = x as string; // null if x is not string
Interview tip: Use as only with nullable/reference targets and remember to check for null. Use pattern matching for most modern code.
Question 3. What is boxing and unboxing?
Answer: Boxing copies a value type into an object/interface container. Unboxing extracts it back with an explicit cast and runtime type check.
int number = 42; object boxed = number; // boxing int unboxed = (int)boxed; // unboxing
Why it matters: Boxing allocates and can hurt performance in loops. Prefer generics such as List<int> over non-generic collections such as ArrayList.
Question 4. Value type vs reference type?
Answer: A value-type variable contains the value itself. Assignment copies the value. A reference-type variable contains a reference to an object. Assignment copies the reference, so both variables can point to the same object.
int a = 10;
int b = a;
b = 20; // a is still 10
var p1 = new Person { Name = "Raj" };
var p2 = p1;
p2.Name = "Updated"; // p1.Name also changedExamples: int, bool, DateTime, decimal, enum, and struct are value types. Classes, arrays, strings, delegates, and records declared as record class are reference types.
Question 5. Do value types inherit from object?
Answer: Yes, but not as reference objects in normal storage. All structs inherit from System.ValueType, which inherits from System.Object. When a value type is used as object or an interface, it is boxed.
int x = 5; object o = x; // boxed Int32 Console.WriteLine(o.GetType()); // System.Int32
Correction: Saying "value types are stored only on stack" is oversimplified. A value type can live inside an object, in an array, in a field, or on the stack depending on context and runtime optimization.
Question 6. Class vs struct: when should each be used?
Answer: Use a class for entities with identity, lifecycle, inheritance, or mutation. Use a struct for small immutable values where copying is cheap.
public readonly struct Money
{
public decimal Amount { get; }
public string Currency { get; }
public Money(decimal amount, string currency) =>
(Amount, Currency) = (amount, currency);
}Interview tip: Avoid large mutable structs because copying can create subtle bugs.
Question 7. Are nullable types reference types?
Answer: No. Nullable<T> is a struct that wraps a value type plus a HasValue flag. int? is shorthand for Nullable<int>.
int? age = null; Console.WriteLine(age.HasValue); // false age = 30; Console.WriteLine(age.Value); // 30
Interview tip: Nullable<T> works only where T is a non-nullable value type.
Question 8. What is the difference between object and System.Object, string and System.String?
Answer: In C#, lowercase aliases map to CLR types. object is System.Object, string is System.String, int is System.Int32, and long is System.Int64.
string a = "hello"; System.String b = "hello"; Console.WriteLine(a.GetType() == b.GetType()); // true
Question 9. Why are strings immutable in C#?
Answer: A string cannot be changed after creation. Operations like Replace, Substring, ToUpper, and concatenation create new strings.
string name = "raj"; string upper = name.ToUpperInvariant(); // name is still "raj"; upper is a new string.
Why it matters: Immutability makes strings safer for sharing, hashing, and interning. For repeated modifications, use StringBuilder.
Question 10. string vs StringBuilder?
Answer: Use string for a small number of concatenations or immutable values. Use StringBuilder when building a string in a loop or many conditional pieces.
var sb = new StringBuilder();
foreach (var item in items)
{
sb.AppendLine(item.Name);
}
string result = sb.ToString();Interview tip: Modern compilers optimize simple concatenations, but not arbitrary loop-based concatenation.
Question 11. How should case-insensitive string comparison be done?
Answer: Use StringComparison or StringComparer. Do not convert both values to upper/lower case just to compare.
bool isAdmin = string.Equals(
input,
"admin",
StringComparison.OrdinalIgnoreCase);Interview tip: Use OrdinalIgnoreCase for identifiers, codes, usernames, keys, and most technical comparisons. Use culture-aware comparison for human language sorting/display.
Question 12. Is string.Empty faster than ""?
Answer: No meaningful performance difference in normal code. Use whichever is the team standard. For readability, many teams use string.Empty for empty values and "" in tests/examples.
if (name == string.Empty) { }
if (name == "") { }
if (string.IsNullOrWhiteSpace(name)) { }Better interview answer: Discuss null/empty/whitespace handling rather than micro-optimizing empty string syntax.
Question 13. What is a verbatim string literal?
Answer: A verbatim string starts with @. It does not treat backslash as an escape character, and it can span multiple lines. Double quotes inside it are escaped by doubling them.
string path1 = @"C:\temp\data.txt"; string path2 = "C:\\temp\\data.txt"; string sql = @" SELECT Id, Name FROM Users WHERE Name = @name"; string quote = @"He said, ""Hello"".";
Question 14. What are raw string literals?
Answer: Raw string literals, introduced in newer C# versions, use triple quotes and are useful for JSON, SQL, regex, and multi-line content with fewer escapes.
string json = """
{
"name": "Raj",
"role": "Software Engineer"
}
""";Interview tip: Verbatim strings are common in legacy code; raw strings are cleaner for modern C# when available.
Question 15. const, readonly, and static readonly?
Answer: const is a compile-time constant and can be inlined into consuming assemblies. readonly is assigned at declaration or in an instance constructor. static readonly is assigned once per type.
public const int MaxRetries = 3; public readonly Guid InstanceId = Guid.NewGuid(); public static readonly TimeSpan Timeout = TimeSpan.FromSeconds(30);
Interview tip: Use const only for true constants that will not change across versions, such as mathematical constants or protocol literals.
Question 16. Static field initializer vs static constructor?
Answer: A static field initializer is concise for simple initialization. A static constructor is useful when initialization needs multiple statements, error handling, or ordering.
public sealed class Settings
{
public static readonly string AppName = "InterviewPrep";
static Settings()
{
// complex one-time initialization if needed
}
}Tip: Avoid heavy work in static constructors because it can delay first use and make failures hard to recover from.
Question 17. What are default access modifiers in C#?
Answer: Top-level types are internal by default. Class members are private by default. Interface members are public by contract. Enum members are public.
class CustomerService // internal by default
{
string _name; // private by default
void Save() { } // private by default
}Correction: A constructor is not generally "private by default". If no constructor is declared for a class, C# provides a public parameterless constructor if the class itself is public, or an internal one for an internal class. If you declare a constructor without an access modifier, that constructor is private.
Question 18. Why do we need namespaces?
Answer: Namespaces organize code and prevent name collisions. Two classes can have the same name if they live in different namespaces.
namespace Billing
{
public class Invoice { }
}
namespace Shipping
{
public class Invoice { }
}Interview tip: Namespaces are about logical organization; assemblies are about deployment/versioning.
Question 19. var vs dynamic?
Answer: var is compile-time type inference. The type is still static and checked by the compiler. dynamic skips compile-time member checking and resolves operations at runtime.
var count = 10; // int // count = "x"; // compile error dynamic value = 10; value = "x"; // allowed Console.WriteLine(value.ToUpper());
Tip: Use var when it improves readability. Use dynamic only for dynamic interop, reflection-like APIs, COM, JSON shapes, or cases where static typing is impossible/awkward.
Question 20. What are numeric literal suffixes?
Answer: Suffixes tell the compiler the intended numeric type.
var f = 0f; // float var d = 0d; // double var m = 0m; // decimal var u = 0u; // uint var l = 0L; // long; prefer uppercase L var ul = 0UL; // ulong
Interview tip: Use decimal for money calculations, not double.
Question 21. decimal vs double vs float?
Answer: float and double are binary floating-point types and are fast, but many decimal fractions cannot be represented exactly. decimal is a base-10 decimal type with higher precision for financial calculations, but it is slower and has a smaller range.
double x = 0.1 + 0.2; // not exactly 0.3 decimal money = 0.1m + 0.2m; // exactly 0.3m
Tip: For currency, use decimal plus explicit rounding rules.
Question 22. What is banker rounding?
Answer: By default, Math.Round uses midpoint-to-even rounding. A value exactly halfway between two numbers rounds to the nearest even result.
Console.WriteLine(Math.Round(2.5)); // 2 Console.WriteLine(Math.Round(3.5)); // 4 var away = Math.Round(2.5, MidpointRounding.AwayFromZero); // 3
Interview tip: Always be explicit about rounding in financial/business rules.
Question 23. What is nameof used for?
Answer: nameof returns the name of a variable, type, or member as a string at compile time. It reduces magic strings and makes refactoring safer.
public void SetName(string name)
{
ArgumentException.ThrowIfNullOrWhiteSpace(name, nameof(name));
}Question 24. What are expression-bodied members?
Answer: They are concise syntax for members that contain a single expression.
public string FullName => $"{FirstName} {LastName}";
public override string ToString() => FullName;Tip: Use them for clarity, not to compress complex logic.
Question 25. What is a tuple / ValueTuple?
Answer: Tuples group multiple values without creating a dedicated class. ValueTuple supports named fields and deconstruction.
public static (bool Success, int Value) TryReadCount(string input)
{
return int.TryParse(input, out var count)
? (true, count)
: (false, 0);
}
var (success, value) = TryReadCount("42");Interview tip: Use a named type when the returned data has domain meaning or is used widely.
Question 26. What is an indexer?
Answer: An indexer lets an object be accessed with array-like syntax.
public class StringDataStore
{
private readonly string[] _items = new string[10];
public string this[int index]
{
get => _items[index];
set => _items[index] = value;
}
}Interview tip: Good use cases include wrappers around collections, lookup objects, and domain-specific access patterns.
Question 27. What is operator overloading?
Answer: Operator overloading lets a type define behavior for operators such as +, -, ==, and comparison operators.
public readonly record struct Money(decimal Amount)
{
public static Money operator +(Money left, Money right) =>
new(left.Amount + right.Amount);
}Tip: Overload operators only when behavior is obvious. If + surprises readers, use a named method.
Question 28. Why can some operators not be applied to generic types?
Answer: Generic type parameters historically did not guarantee that operators exist. Modern C# supports generic math through static abstract interface members, but older code often needs constraints, delegates, or explicit methods.
// Modern generic math style, when available:
public static T Add<T>(T a, T b) where T : System.Numerics.IAdditionOperators<T, T, T>
=> a + b;Question 29. What causes OutOfMemoryException?
Answer: It can happen when the runtime cannot allocate required memory. Causes include actually exhausting memory, needing a large contiguous block, 32-bit address-space limits, very large collections, unmanaged memory leaks, pinned-object fragmentation, or loading too much data at once.
// Bad for very large files
var allText = File.ReadAllText(path);
// Better for streaming
foreach (var line in File.ReadLines(path))
{
Process(line);
}Interview tip: Do not only say "RAM is full". Mention address space, large object heap, unmanaged resources, and streaming.
Question 30. What is the stack and heap in .NET?
Answer: The stack stores call frames and local variables for a thread. The managed heap stores objects managed by the GC. But do not overstate it: value types can be fields inside heap objects, and JIT optimizations can change where things physically live.
var customer = new Customer(); // object on managed heap int count = 10; // local value, usually stack/register
Interview tip: The useful distinction is lifetime and ownership, not memorizing "value type stack, reference type heap".