December Code

C# methods and parameters interview questions, with answers

Method questions in C# are about what crosses the call boundary: whether a method gets a copy or the caller's own variable, how a method returns more than one value, and the conveniences C# adds on top, from optional arguments to methods that appear to belong to types you did not write. Every answer below comes with code whose output was produced by compiling and running it on .NET 10.

The questions start with the parameter modifiers, move through the ways arguments can be supplied, and end with extension methods and local functions. Then take the free C# diagnostic — ten questions across every C# topic in the bank — to see which of these you can explain but not yet predict.

The questions, with answers

  1. 1.What is the difference between ref, out and in parameters in C#?

    In short: All three pass the caller's variable by reference: ref must be assigned before the call and may be changed, out must be assigned by the method, and in is read-only.

    Without a modifier, C# copies the argument. ref passes the variable itself, so the method can read it and assign to it, and the caller must initialise it first; the call repeats the keyword, Swap(ref m, ref n), so the possible change is visible at the call site. out also passes the variable, but the method must assign it before returning and may not read it first, which is how TryParse-style methods return a result alongside a success flag; since C# 7 the variable can be declared in the call, as out int q below. in passes a read-only reference, used for large structs to avoid a copy without allowing changes. Tuples are often a cleaner way than out to return several values.

    int m = 1, n = 2;
    Swap(ref m, ref n);
    Console.WriteLine($"{m} {n}");
    Split(17, out int q,
        out int r);
    Console.WriteLine($"{q} {r}");
    
    static void Swap(ref int x,
        ref int y)
        => (x, y) = (y, x);
    static void Split(int v,
        out int q, out int r)
    {
        q = v / 5;
        r = v % 5;
    }
    // 2 1
    // 3 2
  2. 2.Are objects passed by reference in C#?

    In short: No: C# passes the reference by value, so a method can change the object it is given but cannot make the caller's variable point to another object, unless the parameter is ref.

    When you pass a class instance, the method receives a copy of the reference. Both references point to the same object, so calling methods on it or changing its properties inside the method is visible to the caller, as the Append below shows. Assigning a new object to the parameter only re-points the method's copy, and the caller's variable is unaffected. Declaring the parameter ref passes the caller's variable itself, so the method can then replace the object the caller sees, as in the second call. Strings look like an exception, because every string operation returns a new string, but they follow the same rule: without ref, a method cannot change which string the caller's variable holds.

    using System.Text;
    
    StringBuilder sb = new("a");
    Touch(sb);
    Console.WriteLine(sb);
    Replace(ref sb);
    Console.WriteLine(sb);
    
    static void Touch(
        StringBuilder s)
    {
        s.Append("b");
        s = new StringBuilder("x");
    }
    static void Replace(
        ref StringBuilder s) =>
        s = new StringBuilder("z");
    // ab
    // z
  3. 3.How do optional and named arguments work in C#?

    In short: An optional parameter declares a default that callers may omit, and a named argument, name: value, lets a caller skip optional parameters or pass arguments in any order.

    A parameter with a default value, such as bool upper = false, is optional: the compiler inserts the default at every call site that leaves it out, which also means that changing a default in a library does not affect callers until they are recompiled. Defaults must be compile-time constants, default(T) or new() of a value type, and optional parameters come after required ones. Named arguments make calls readable and let a caller set a later optional parameter while keeping earlier defaults, as the second call below does. They interact with overloads: if a call matches both an overload without the parameter and one where it is optional, the one that needs no default wins.

    Console.WriteLine(
        Tag("pen"));
    Console.WriteLine(
        Tag("ink", upper: true));
    
    static string Tag(string s,
        string pre = "#",
        bool upper = false)
        => pre + (upper
            ? s.ToUpper() : s);
    // #pen
    // #INK
  4. 4.What does the params keyword do in C#?

    In short: It lets a method's last parameter accept any number of arguments, which the compiler packs into an array or, since C# 13, into a span or another collection type.

    Declaring static int Sum(params int[] v) lets callers write Sum(4, 5, 6), Sum() or pass an existing array, Sum(arr); for the first two the compiler builds the array at the call site, as below. params must be on the last parameter and a method can have only one. C# 13 extended it to other collection types, such as params ReadOnlySpan<int>, which can avoid the heap allocation entirely. The classic pitfalls come with object: a method taking params object[] and called with a single object[] treats it as the whole argument list rather than as one element, and passing null gives a null array, not an array containing null. Console.WriteLine and string.Format are built on params.

    Console.WriteLine(Sum());
    int t = Sum(4, 5, 6);
    Console.WriteLine(t);
    int[] arr = { 1, 2 };
    Console.WriteLine(Sum(arr));
    
    static int Sum(
        params int[] v) => v.Sum();
    // 0
    // 15
    // 3
  5. 5.What are extension methods in C#?

    In short: Static methods whose first parameter is marked this, declared in a static class, which callers invoke as if they were instance methods of that type; LINQ is built from them.

    An extension method lets you add a method to a type you cannot change, such as string or an interface. It is an ordinary static method in a static class, with this before its first parameter, as Words below. When its namespace is in scope, the compiler rewrites "to be or not".Words() into StringExt.Words("to be or not"), so no inheritance or access to private members is involved, and an instance method with the same signature always wins. Extension methods on interfaces are how LINQ adds Where and Select to every IEnumerable<T>. C# 14 adds extension blocks, which can also declare extension properties. Because they are bound at compile time, extension methods cannot be overridden.

    Console.WriteLine(
        "to be or not".Words());
    
    static class StringExt
    {
        public static int Words(
            this string s) =>
            s.Split(' ').Length;
    }
    // 4
  6. 6.What is a local function in C#, and how is it different from a lambda?

    In short: A local function is a named method declared inside another method; unlike a lambda it can be generic, recursive and an iterator without a delegate, and a static one cannot capture.

    A local function, declared inside a method's body, is visible only there, which keeps a helper next to its only caller. Compared with a lambda assigned to a Func, it has a name, so recursion is natural, as below; it can be generic, use yield return, and be declared after the code that calls it; and calling it needs no delegate object, so it usually allocates nothing even when it captures variables. Marking it static forbids capturing locals or this, which prevents accidental captures and their allocations. A lambda is still the right tool when you need a delegate value to hand to other code, as with LINQ. In a top-level program, every method you declare is a local function, as in these examples.

    Console.WriteLine(Fact(5));
    
    static long Fact(int n)
    {
        return n <= 1 ? 1
            : n * Fact(n - 1);
    }
    // 120

How the diagnostic asks it

One question from the C# bank, exactly as a sitting would show it. The bank has 3 on methods & parameters and 30 across C#.

Methods & Parameters · easyCSHARP-018

What does this C# code print?

bool ok = int.TryParse("12a", out int n);
Console.WriteLine($"{ok} {n}");
  1. 1True 12
  2. 2False 0correct
  3. 3False 12
  4. 4It throws a FormatException

int.TryParse never throws for bad input: it returns false, and because n is an out parameter, which the method must assign before returning, it sets n to 0. So the output is False 0. True 12 assumes parsing stops at the first non-digit and keeps what it has, but the whole string must be a valid number. False 12 assumes n keeps a partial result. A FormatException is what int.Parse("12a") throws; TryParse exists so invalid input can be handled without an exception. out int n declares the variable right inside the call.

Measure it

Reading answers tells you what’s true. A diagnostic tells you what you get wrong.

10 C# questions across its topics, easy to hard, about fifteen minutes. You get a readiness figure with the arithmetic shown, the topics you missed named, and a practice set sized for today. Free: 1 diagnostic a month and 15 problems a day. No card.

What the readiness test measures · how the score is computed

By Harshit · updated