Parameter Passing in C#: Interview Questions and Answers
Questions on ref, out, in and params are asked in almost every C# interview, for freshers and experienced developers alike. Interviewers also love "what is the output?" questions here. If you are new to the topic, first read the lesson Parameter Passing Techniques in C#, then practise with these questions.
Basic Questions
1. What is the difference between a parameter and an argument?
A parameter is the variable declared in the method definition, for example a in void Print(int a). An argument is the actual value passed when calling the method, for example 10 in Print(10).
2. What are the parameter passing techniques in C#?
- Pass by value (default, no keyword)
- Pass by reference using
ref - Output parameters using
out - Read-only reference using
in - Variable number of arguments using
params - Optional parameters and named arguments (ways of supplying arguments)
3. What is the default parameter passing technique in C#?
Pass by value. The method receives a copy of the argument. For value types it is a copy of the value; for reference types it is a copy of the reference (address).
4. What is the difference between pass by value and pass by reference?
| Pass by value | Pass by reference (ref/out/in) |
|---|---|
| A copy of the variable is passed | The variable itself (its memory location) is passed |
| Assigning to the parameter does not affect the caller | Assigning to the parameter changes the caller's variable (except in, which is read-only) |
| No keyword needed | Keyword in the method definition (and at the call for ref/out) |
5. Are reference types passed by reference in C#?
No, this is a very common misunderstanding. Reference types are also passed by value by default, but the value being copied is the reference. That's why the method can change the object's properties (both references point to the same object) but cannot make the caller's variable point to a new object, unless you use ref.
6. What is the ref keyword?
ref passes an argument by reference. The variable must be initialised before the call, and the method can read and modify it. Changes are visible to the caller. ref must be written in both the method definition and the call.
7. What is the out keyword?
out passes an argument by reference to receive a value from the method. The variable need not be initialised before the call, but the method must assign it before returning. It is commonly used to return multiple values, as in int.TryParse(text, out int number).
8. What is the difference between ref and out?
ref | out |
|---|---|
| Must be initialised before passing | Need not be initialised before passing |
| The method may or may not change it | The method must assign a value before returning |
| Can be read inside the method immediately | Cannot be read inside the method until it is assigned |
| Two-way: data goes in and comes out | One-way: data only comes out |
| Use: swap values, update a counter | Use: return multiple values, TryParse |
9. What is the in keyword?
in (C# 7.2) passes an argument by reference but makes it read-only inside the method. It avoids copying large structs while guaranteeing the method can't change them. The in keyword is optional at the call site.
10. What is the params keyword?
params lets a method accept a variable number of arguments, which arrive as an array:
static int Sum(params int[] numbers) => numbers.Sum();
Sum(); // 0
Sum(1, 2, 3); // 6
Rules: only one params parameter per method, it must be the last parameter, and it cannot be combined with ref, out or in.
11. What are optional parameters?
Parameters with a default value, for example void Print(string text, int copies = 1). If the caller skips them, the default is used. They must come after all required parameters, and the default must be a compile-time constant.
12. What are named arguments?
Arguments passed by parameter name, for example Print(text: "Hi", copies: 3). They improve readability, allow any order, and let you skip optional parameters in the middle: PrintBill("Bag", discount: 10).
Intermediate Questions
13. Can we overload methods based on ref and out?
You can overload a method on ref/out versus no keyword:
void Update(int x) { }
void Update(ref int x) { } // OK
But you cannot overload methods that differ only by ref and out (or in), because at the IL level they are all the same "by reference" parameter:
void Update(ref int x) { }
void Update(out int x) { x = 0; } // error CS0663
14. Can a property or indexer be passed as a ref or out argument?
No. A property is really a pair of methods (get/set), not a storage location, so it can't be passed by reference. Copy it into a local variable first, pass the local, and assign it back. (A field can be passed with ref.)
15. Can async methods have ref, out or in parameters?
No. Async methods (and iterators using yield) cannot have ref, out or in parameters, because the method may pause and resume after the caller's variable has gone out of scope. Return a Task<T> or a tuple instead.
16. Can lambda expressions capture ref or out parameters?
No. A lambda or anonymous method cannot use a ref, out or in parameter of the enclosing method (error CS1628), because the lambda could run after the method has returned. Copy the value into a local variable and capture that.
17. What is the out discard (_) and inline out variable declaration?
From C# 7 you can declare the out variable in the call and discard values you don't need:
if (int.TryParse(input, out int age)) { ... } // inline declaration
if (int.TryParse(input, out _)) { ... } // only check, ignore the value
18. Is it better to use out parameters or tuples to return multiple values?
For new code, tuples are usually cleaner: (int Min, int Max) GetRange(). They read better and work with async methods. out is still preferred for the Try pattern (TryParse, TryGetValue), where the method returns bool and gives the value through out.
19. What happens if you pass a string to a method and modify it?
The caller's string does not change. string is a reference type, but it is immutable: any "modification" creates a new string object, and only the method's local copy of the reference points to it. Use ref string or return the new string if the caller needs it.
20. When would you use in instead of passing by value?
When passing a large struct (for example a struct with many fields) to a method that is called often. in avoids copying the whole struct on every call. For small types like int or double there is no benefit. Best used with readonly struct types, otherwise the compiler may make hidden "defensive copies" when calling methods on the parameter.
What is the Output? (Tricky Questions)
21. Value type passed by value
static void Change(int x) { x = 100; }
int a = 5;
Change(a);
Console.WriteLine(a);
Output: 5. The method changed only its copy.
22. Object passed by value, property changed
class Box { public int Size; }
static void Change(Box b) { b.Size = 50; }
Box box = new Box { Size = 10 };
Change(box);
Console.WriteLine(box.Size);
Output: 50. Both references point to the same object, so the change to its field is visible.
23. Object passed by value, new object assigned
static void Change(Box b)
{
b = new Box { Size = 99 };
}
Box box = new Box { Size = 10 };
Change(box);
Console.WriteLine(box.Size);
Output: 10. Only the method's copy of the reference now points to the new object; the caller's box is unchanged.
24. Object passed by ref, new object assigned
static void Change(ref Box b)
{
b = new Box { Size = 99 };
}
Box box = new Box { Size = 10 };
Change(ref box);
Console.WriteLine(box.Size);
Output: 99. With ref, the caller's variable itself is replaced.
25. Modify, then reassign
static void Change(Box b)
{
b.Size = 20;
b = new Box { Size = 30 };
b.Size = 40;
}
Box box = new Box { Size = 10 };
Change(box);
Console.WriteLine(box.Size);
Output: 20. The first line changes the caller's object. After b is pointed to a new object, further changes affect only that new object.
26. Array passed by value
static void Change(int[] arr)
{
arr[0] = 100;
arr = new int[] { 7, 8, 9 };
}
int[] numbers = { 1, 2, 3 };
Change(numbers);
Console.WriteLine(string.Join(",", numbers));
Output: 100,2,3. Arrays are reference types: the element change is visible, the reassignment is not.
27. Will this code compile?
static void GetData(out int x)
{
Console.WriteLine(x);
x = 10;
}
No. An out parameter is treated as unassigned at the start of the method, so reading it before assigning gives error CS0269 ("Use of unassigned out parameter 'x'").
28. Will this code compile?
int count;
Increase(ref count);
static void Increase(ref int n) { n++; }
No. A ref argument must be definitely assigned before the call (error CS0165, "Use of unassigned local variable 'count'"). Initialise it first, for example int count = 0;.
29. What does this print?
static void Show(string name = "Guest", int age = 18)
{
Console.WriteLine($"{name} - {age}");
}
Show();
Show("Riya");
Show(age: 25);
Output:
30. String passed by value
static void AddTitle(string name)
{
name = "Mr. " + name;
}
string person = "Amit";
AddTitle(person);
Console.WriteLine(person);
Output: Amit. Strings are immutable; the method's assignment creates a new string that only the local copy refers to.
Summary
- Everything is passed by value by default, including references.
ref: initialised before, two-way.out: not initialised before, must be assigned inside.in: by reference, read-only.params: one per method, last parameter, an array of any length.- You can't overload on
refvsoutalone; properties, async methods and lambdas have restrictions with by-reference parameters. - For reference types: changing the object's data is visible to the caller, reassigning the parameter is not (unless
ref).