Skip to content
Search lessons, topics, tests…
Esc

    ↑ ↓ moveEnter openEsc close

    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.

    C#
    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 text

    Interview 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.

    C#
    object x = 10;
    if (x is int y)
    {
        Console.WriteLine(y + 1);
    }
    C#
    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.

    C#
    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.

    C#
    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 changed

    Examples: 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.

    C#
    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.

    C#
    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>.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    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.

    C#
    // 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.

    C#
    // 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.

    C#
    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".

    Sign in to mark lessons done and keep your place in the course.Sign in