Menu
CoddyTech

C# Basics Interview Questions

Types, operators, strings, nullable values and exceptions, the basics of every campus and junior round.

17 questions
  1. What is C# and how is it related to .NET?

    C# is a statically typed, object-oriented language from Microsoft. The compiler turns it into IL (intermediate language), and the .NET runtime (the CLR) compiles that IL to machine code when the program runs. .NET is the platform around the language: the runtime, the base class library and the SDK. More in What is C#.

  2. What are the built-in data types in C#?

    C# has value types for numbers, characters and booleans (int, long, double, decimal, bool, char), plus string and object as built-in reference types. Each keyword aliases a .NET type: int is System.Int32. Use decimal for money.

    C#
    using System;
    
    class Program
    {
        static void Main()
        {
            Console.WriteLine(sizeof(int) + " " + sizeof(long) + " " + sizeof(decimal) + " " + sizeof(char));
            Console.WriteLine(int.MaxValue);
            Console.WriteLine(typeof(int).FullName);
        }
    }

    Trap: char is 2 bytes, one UTF-16 code unit, not a byte as in C.

  3. What is the difference between string and String in C#?

    There is no difference: string is the C# keyword for System.String, and both compile to the same IL, as do int and Int32. Use the keyword in declarations. String needs using System;; string never does.

  4. What do 7 / 2 and 7 / 2.0 evaluate to in C#?

    C#
    using System;
    
    class Program
    {
        static void Main()
        {
            Console.WriteLine(7 / 2 + " " + 7 / 2.0 + " " + 7 % 3);
        }
    }

    7 / 2 divides two int values, so the fraction is dropped: 3. With one double operand (2.0) the division is floating point: 3.5. 7 % 3 is the remainder, 1.

    For an average, cast first: (double)sum / count, not (double)(sum / count), which has already truncated.

  5. What is i++ + ++i when i starts at 5?

    C#
    using System;
    
    class Program
    {
        static void Main()
        {
            int i = 5;
            Console.WriteLine(i++ + ++i);
        }
    }

    C# evaluates operands left to right, so the result is defined (in C it is undefined behavior). i++ yields 5 and sets i to 6; ++i sets i to 7 and yields 7. The sum is 12.

  6. What is the difference between const and readonly in C#?

    A const is a compile-time constant, implicitly static, limited to numbers, bool, char, string, enums and null. A readonly field can be any type and is set once at run time, in its declaration or a constructor.

    class Config
    {
        public const int MaxUsers = 100;              // baked into callers at compile time
        public static readonly DateTime Started = DateTime.Now; // computed at runtime
        public readonly Guid Id;
    
        public Config() { Id = Guid.NewGuid(); }       // readonly can be set here
    }
    

    Trap: a public const is copied into every assembly that uses it, so callers keep the old value until they are recompiled. Use static readonly for values that might change.

  7. What is the difference between ref and out parameters?

    Both pass a variable by reference. A ref argument must be initialized before the call; an out parameter need not be, but the method must assign it before returning.

    C#
    using System;
    
    class Program
    {
        static void Double(ref int x) { x *= 2; }
    
        static bool TryHalf(int n, out int half)
        {
            half = n / 2;
            return n % 2 == 0;
        }
    
        static void Main()
        {
            int value = 21;
            Double(ref value);
            Console.WriteLine(value);
    
            if (TryHalf(value, out int h))
                Console.WriteLine("half is " + h);
        }
    }

    out is the pattern behind int.TryParse. See ref and out.

  8. What are tuples in C#, and how do you return multiple values from a method?

    C# 7 tuples (System.ValueTuple) group a few values without declaring a type, such as (int min, int max), and are the usual way to return several values from a private method.

    C#
    using System;
    
    class Program
    {
        static (int min, int max) MinMax(int[] nums)
        {
            int min = nums[0], max = nums[0];
            foreach (int n in nums)
            {
                if (n < min) min = n;
                if (n > max) max = n;
            }
            return (min, max);
        }
    
        static void Main()
        {
            var r = MinMax(new[] { 4, 9, 1, 7 });
            Console.WriteLine(r.min + " " + r.max);
    
            var (lo, hi) = MinMax(new[] { 3, 8 });   // deconstruction
            Console.WriteLine(lo + " " + hi);
    
            int a = 1, b = 2;
            (a, b) = (b, a);                        // swap without a temp variable
            Console.WriteLine(a + " " + b);
        }
    }

    Trap: the element names exist only at compile time; at run time the fields are Item1, Item2. See tuples.

  9. Does == compare strings by value or by reference in C#?

    C#
    using System;
    
    class Program
    {
        static void Main()
        {
            string a = "hello";
            string b = new string("hello".ToCharArray());
            Console.WriteLine((a == b) + " " + ((object)a == (object)b) + " " + a.Equals(b));
        }
    }

    == on two string variables is overloaded to compare characters: True. Cast to object, == compares references, and new string(...) made a second object: False. Equals is virtual and String overrides it to compare values: True. == is chosen at compile time from the static types.

  10. Why are strings immutable in C#, and when should you use StringBuilder?

    A string never changes after it is created; +, Replace and ToUpper return new strings, which makes strings safe to share between threads. Use StringBuilder to build a string in a loop, because it appends into one buffer instead of copying the whole text each step.

    C#
    using System;
    using System.Text;
    
    class Program
    {
        static void Main()
        {
            string s = "abc";
            string t = s.ToUpper();
            Console.WriteLine(s + " " + t);
    
            var sb = new StringBuilder();
            for (int i = 1; i <= 5; i++)
                sb.Append(i).Append(',');
            sb.Length--;              // drop the last comma
            Console.WriteLine(sb.ToString());
        }
    }

    See StringBuilder.

  11. What is boxing and unboxing in C#?

    Boxing copies a value type into a new heap object so it can be used as object or an interface; unboxing copies it back out with a cast. Both cost time in hot loops.

    C#
    using System;
    
    class Program
    {
        static void Main()
        {
            int n = 42;
            object boxed = n;        // boxing: new object on the heap
            int back = (int)boxed;   // unboxing: type check and copy
            Console.WriteLine(back);
    
            try
            {
                long wrong = (long)boxed;  // must unbox to the exact type
                Console.WriteLine(wrong);
            }
            catch (InvalidCastException)
            {
                Console.WriteLine("InvalidCastException");
            }
        }
    }

    Trap: unboxing must use the exact boxed type, so a boxed int becomes a long with (long)(int)boxed.

  12. Are two boxed ints equal under ==? And under Equals?

    C#
    using System;
    
    class Program
    {
        static void Main()
        {
            object a = 1;
            object b = 1;
            Console.WriteLine((a == b) + " " + a.Equals(b));
        }
    }

    Each assignment boxes the 1 into a separate object. == on two object variables compares references: False. Equals is virtual, and the boxed Int32 compares values: True. Compare values that travel as object with Equals.

  13. What are nullable types, and what do ?, ?? and ?. do?

    int? (Nullable<int>) is a value type that can also hold null. ?? returns the right side when the left side is null; ?. calls a member only on a non-null object and gives null otherwise.

    C#
    using System;
    
    class Program
    {
        static void Main()
        {
            int? age = null;
            Console.WriteLine(age.HasValue);
            Console.WriteLine(age ?? 18);
    
            string name = null;
            int? length = name?.Length;
            Console.WriteLine(length == null);
            Console.WriteLine(name?.Length ?? 0);
        }
    }

    Trap: .Value on a null int? throws InvalidOperationException. See nullable types.

  14. What is the difference between var, dynamic and object?

    var lets the compiler infer the static type, so the variable stays strongly typed. object is the base type of everything and needs casts. dynamic skips compile-time checks and resolves members at run time.

    var count = 10;          // count is an int; count = "x" does not compile
    object o = 10;           // int boxed as object; o + 1 does not compile
    int n = (int)o + 1;      // a cast is needed
    
    dynamic d = 10;
    d = d + 1;               // resolved at runtime
    d.Foo();                 // compiles, throws RuntimeBinderException when run
    

    Use dynamic only for COM interop or truly dynamic data.

  15. What are the access modifiers in C#?

    C# has six access levels; the defaults are private for class and struct members and internal for top-level types. C# 11 also adds file, which limits a top-level type to its source file (see access modifiers).

    ModifierAccessible from
    publicanywhere
    privatethe same class
    protectedthe class and derived classes
    internalthe same assembly
    protected internalsame assembly or derived classes
    private protectedderived classes in the same assembly

    Trap: internal means the assembly, not the namespace.

  16. What happens when you add 1 to int.MaxValue in C#?

    C#
    using System;
    
    class Program
    {
        static void Main()
        {
            int x = int.MaxValue;
            x++;
            Console.WriteLine(x);
        }
    }

    Integer arithmetic is unchecked by default (unless the project sets CheckForOverflowUnderflow), so adding 1 to int.MaxValue wraps to int.MinValue, -2147483648, with no exception. A checked block or checked(x + 1) throws OverflowException instead. A constant expression such as int.MaxValue + 1 is a compile error.

  17. In what order do a return in try and its finally block run?

    C#
    using System;
    
    class Program
    {
        static int F()
        {
            try
            {
                return 1;
            }
            finally
            {
                Console.Write("finally ");
            }
        }
    
        static void Main()
        {
            Console.WriteLine(F());
        }
    }

    finally runs whenever control leaves the try block, including through return. The value 1 is computed, finally writes finally , and then the method returns, so Main prints 1 after it. A return inside finally is a compile error in C#.

Coddy programming languages illustration

Learn to code with Coddy

Get started