C# quiz and interview questions
C# interviews test three things: whether you know how the type system works (value vs reference, boxing, immutability), whether you can read code and predict what it prints, and whether you can spot bugs like off-by-one errors, async void and deadlocks. The quiz below mixes all three, from junior to senior level.
C#: key concepts
- Value vs reference types
- Structs, int, double and bool are value types: assigning copies the data. Classes, string, arrays and object are reference types: assigning copies the reference, so both variables point to the same object.
- Strings are immutable
- Methods like ToUpper() or Replace() return a new string and never change the original. Use StringBuilder when you build long strings in a loop.
- LINQ deferred execution
- Where, Select and most LINQ operators don't run until you enumerate (foreach, ToList, Count). If the source changes before that, the result reflects the change.
- async / await
- await frees the thread while waiting for I/O. Return Task (not void) from async methods so callers can await them and catch exceptions; avoid .Result and .Wait(), which can deadlock.
- Boxing
- Converting a value type to object or an interface allocates a copy on the heap. It's slow in hot loops — generics avoid it.
- IDisposable and using
- Objects that hold files, connections or sockets implement IDisposable. A using statement calls Dispose() automatically, even when an exception is thrown.
All 90 C# questions with answers
Try each one first, then open the answer. Making a class test? Use the test maker.
Which of these is a value type in C#?
- A. string
- B. int
- C. object
- D. int[]
Show answer
B. int — int (System.Int32) is a struct, so it's a value type. string, object and arrays are reference types.
What does this print?
int a = 5; int b = a++ + ++a; Console.WriteLine(b);- A. 10
- B. 11
- C. 12
- D. 13
Show answer
C. 12 — a++ returns 5 and then a becomes 6. ++a makes a 7 and returns 7. So b = 5 + 7 = 12.
What does this print?
string s = "hello"; s.ToUpper(); Console.WriteLine(s);- A. HELLO
- B. hello
- C. Hello
- D. Compile error
Show answer
B. hello — Strings are immutable. ToUpper() returns a new string, but the result is thrown away, so s is still "hello".
What is the main difference between const and readonly?
- A. There is no difference
- B. readonly can be assigned in the constructor; const must be set at compile time
- C. const can be changed later; readonly can't
- D. readonly only works with strings
Show answer
B. readonly can be assigned in the constructor; const must be set at compile time — const values are baked in at compile time. readonly fields can be set at declaration or in a constructor, so they can hold runtime values.
What goes wrong when this runs?
int[] nums = { 1, 2, 3 }; for (int i = 0; i <= nums.Length; i++) Console.WriteLine(nums[i]);- A. Syntax error
- B. Prints 1 2 3 and stops normally
- C. Prints 1 2 3, then throws IndexOutOfRangeException
- D. Infinite loop
Show answer
C. Prints 1 2 3, then throws IndexOutOfRangeException — Off-by-one error: valid indexes are 0–2, but i <= nums.Length also tries nums[3]. Use i < nums.Length.
What does this print?
var actions = new List<Action>(); for (int i = 0; i < 3; i++) actions.Add(() => Console.Write(i)); foreach (var a in actions) a();- A. 012
- B. 333
- C. 222
- D. 000
Show answer
B. 333 — The lambdas capture the same loop variable i, not its value at that moment. When they run, the loop has finished and i is 3. (foreach loops get a fresh variable per iteration since C# 5; for loops don't.)
What does this print?
var list = new List<int> { 1, 2, 3 }; var query = list.Where(x => x > 1); list.Add(4); Console.WriteLine(query.Count());- A. 2
- B. 3
- C. 4
- D. 1
Show answer
B. 3 — LINQ is deferred: Where runs only when Count() enumerates it, after 4 was added. Matching items are 2, 3 and 4.
What is boxing?
- A. Wrapping code in a try/catch
- B. Converting a value type to object (a heap allocation)
- C. Casting a class to an interface
- D. Compressing a string
Show answer
B. Converting a value type to object (a heap allocation) — Boxing copies a value type into a new object on the heap, e.g. object o = 42;. Unboxing casts it back. It costs memory and time in hot paths.
What is the main problem with this method?
public async void SaveAsync() { await db.SaveChangesAsync(); }- A. It won't compile
- B. Callers can't await it and exceptions can crash the app
- C. It runs synchronously
- D. SaveChangesAsync doesn't exist
Show answer
B. Callers can't await it and exceptions can crash the app — async void can't be awaited, so callers don't know when it finishes and can't catch its exceptions. Use async Task — async void is only for event handlers.
What does this print?
struct Point { public int X; } var p1 = new Point { X = 1 }; var p2 = p1; p2.X = 5; Console.WriteLine(p1.X);- A. 5
- B. 1
- C. 0
- D. Compile error
Show answer
B. 1 — Point is a struct (value type), so p2 = p1 copies it. Changing p2 doesn't affect p1.
Why implement IDisposable and use a using statement?
- A. To make the garbage collector run faster
- B. To release unmanaged resources (files, connections) deterministically
- C. To make a class thread-safe
- D. To allow inheritance
Show answer
B. To release unmanaged resources (files, connections) deterministically — The GC frees memory eventually, but not handles like DB connections or file locks. using calls Dispose() at the end of the block, even on exceptions.
What does this print?
object a = "hi"; object b = new string(new[] { 'h', 'i' }); Console.WriteLine(a == b); Console.WriteLine(a.Equals(b));- A. True True
- B. False True
- C. True False
- D. False False
Show answer
B. False True — With object variables, == compares references, and these are two different string objects → False. Equals is virtual, so string's value comparison runs → True.
In a WinForms/WPF button handler, what can this line cause?
var data = GetDataAsync().Result;- A. Nothing — it's the normal way to call async code
- B. A deadlock that freezes the UI
- C. A compile error
- D. Data is returned twice
Show answer
B. A deadlock that freezes the UI — .Result blocks the UI thread, while the async method needs that same thread to continue after await. Each waits for the other. Make the handler async and await the call.
With Entity Framework, what is the key difference between IQueryable and IEnumerable?
- A. No difference
- B. IQueryable builds an expression that is translated to SQL; IEnumerable filters in memory
- C. IEnumerable is faster for databases
- D. IQueryable can only be used with arrays
Show answer
B. IQueryable builds an expression that is translated to SQL; IEnumerable filters in memory — Filtering an IQueryable adds to the SQL query, so the database does the work. Calling AsEnumerable()/ToList() first loads rows into memory and filters there.
What does this print?
Console.WriteLine(7 / 2);- A. 3.5
- B. 3
- C. 4
- D. 3.0
Show answer
B. 3 — Both operands are int, so this is integer division and the decimal part is dropped. Use 7 / 2.0 to get 3.5.
What is wrong with this line?
int count = "5";- A. Nothing
- B. Compile error: can't implicitly convert string to int
- C. Runtime exception
- D. count becomes 0
Show answer
B. Compile error: can't implicitly convert string to int — C# is statically typed. Use int.Parse("5") or int.TryParse to convert text to a number.
Which keyword stops other classes from inheriting a class?
- A. static
- B. sealed
- C. private
- D. readonly
Show answer
B. sealed — A sealed class can't be used as a base class. string is a well-known sealed class.
Does C# support multiple inheritance of classes?
- A. Yes, any number of base classes
- B. No — one base class, but many interfaces
- C. Only for abstract classes
- D. Only with the partial keyword
Show answer
B. No — one base class, but many interfaces — A class has exactly one base class, which avoids the "diamond problem". It can implement as many interfaces as it needs.
A field declared inside a class with no access modifier is…
- A. public
- B. internal
- C. private
- D. protected
Show answer
C. private — Class members default to private. A top-level class itself defaults to internal.
What is the default access level of a top-level class with no modifier?
- A. public
- B. internal
- C. private
- D. protected
Show answer
B. internal — Top-level types are internal by default: visible inside the same assembly (project) only.
Two methods have the same name and parameters but different return types. What happens?
- A. They're valid overloads
- B. Compile error — return type alone can't distinguish overloads
- C. The last one wins
- D. Runtime error
Show answer
B. Compile error — return type alone can't distinguish overloads — Overloads must differ in their parameter list. The compiler can't choose between methods that differ only by return type.
If a base class method is virtual, must the derived class override it?
- A. Yes, always
- B. No — overriding is optional
- C. Only if the class is abstract
- D. Only for public methods
Show answer
B. No — overriding is optional — virtual allows overriding but doesn't require it. abstract methods are the ones that must be overridden.
Can an interface declare a constructor?
- A. Yes
- B. No
- C. Only a static one in C# 1
- D. Only a private one
Show answer
B. No — Interfaces can't be instantiated, so they have no instance constructors. Implementing classes provide their own.
Can an abstract class have a constructor?
- A. No, never
- B. Yes — derived class constructors call it to set up shared state
- C. Only a static constructor
- D. Only if it has no abstract methods
Show answer
B. Yes — derived class constructors call it to set up shared state — You can't create the abstract class directly, but its constructor runs when a derived class is created (via base(...)).
Which modifier can't be combined with abstract on a class?
- A. public
- B. sealed
- C. partial
- D. internal
Show answer
B. sealed — abstract means "must be inherited" and sealed means "can't be inherited" — together they make no sense, so the compiler rejects it (static abstract classes are also not allowed).
In modern C# (8 and later), can an interface method have a body?
- A. No, never
- B. Yes — default interface methods
- C. Only private methods
- D. Only in .NET Framework
Show answer
B. Yes — default interface methods — Default interface methods let you add members to an interface without breaking existing implementers.
What does this print?
var sb = new StringBuilder("Hi"); sb.Append("!"); sb.Insert(0, ">"); Console.WriteLine(sb);- A. Hi!
- B. >Hi!
- C. Hi!>
- D. >Hi
Show answer
B. >Hi! — StringBuilder changes the same buffer: Append adds "!" at the end, Insert(0, ">") adds ">" at the start.
What does this print?
int qty = 3; decimal price = 2.5m; Console.WriteLine($"{qty} x {price} = {qty * price}");- A. 3 x 2.5 = 7.5
- B. {qty} x {price} = {qty * price}
- C. 3 x 2.5 = 7
- D. Compile error
Show answer
A. 3 x 2.5 = 7.5 — $"..." is string interpolation: expressions inside braces are evaluated. 3 × 2.5m = 7.5.
When should you use StringBuilder instead of string?
- A. Always
- B. When building a string from many pieces, e.g. in a loop
- C. For very short strings
- D. When the string is constant
Show answer
B. When building a string from many pieces, e.g. in a loop — Each string + creates a new string object. In loops, StringBuilder appends to one buffer and is much faster.
What does this print?
try { Console.Write("A"); throw new Exception(); } catch { Console.Write("B"); } finally { Console.Write("C"); } Console.Write("D");- A. AD
- B. ABD
- C. ABCD
- D. ACD
Show answer
C. ABCD — A prints, the exception jumps to catch (B), finally always runs (C), and execution continues after the block (D).
What does this print?
try { int.Parse("x"); } catch (FormatException) { Console.Write("format"); } catch (Exception) { Console.Write("general"); }- A. format
- B. general
- C. formatgeneral
- D. Nothing
Show answer
A. format — int.Parse("x") throws FormatException. Only the first matching catch block runs.
Why doesn't this compile?
try { /* ... */ } catch (Exception) { } catch (FormatException) { }- A. try needs finally
- B. The general catch comes first, so the FormatException catch can never run
- C. Exceptions need a variable name
- D. FormatException doesn't exist
Show answer
B. The general catch comes first, so the FormatException catch can never run — Order catch blocks from most specific to most general. Exception already catches FormatException, so the second block is unreachable (CS0160).
Inside a catch block, what is the difference between throw; and throw ex;?
- A. None
- B. throw; keeps the original stack trace; throw ex; resets it
- C. throw ex; is faster
- D. throw; swallows the exception
Show answer
B. throw; keeps the original stack trace; throw ex; resets it — throw ex; makes the stack trace start at the catch block, hiding where the error really happened. Use throw; to rethrow.
What is the difference between finally and Finalize?
- A. They are the same
- B. finally is a block that always runs after try/catch; Finalize is a method the garbage collector calls before freeing an object
- C. Finalize runs first
- D. finally is only for files
Show answer
B. finally is a block that always runs after try/catch; Finalize is a method the garbage collector calls before freeing an object — finally is for cleanup in your own code flow. Finalize (a C# destructor) is called by the GC at an unpredictable time.
What is the main difference between an array and a List<T>?
- A. Arrays can hold objects; lists can't
- B. An array has a fixed size; a List<T> grows and shrinks as you add or remove items
- C. Lists are slower to read by index
- D. Arrays are always sorted
Show answer
B. An array has a fixed size; a List<T> grows and shrinks as you add or remove items — new int[5] always holds 5 items. A List<int> resizes itself as you call Add or Remove.
What is the average cost of looking up a value by key in a Dictionary<TKey, TValue>?
- A. O(n)
- B. O(log n)
- C. O(1)
- D. O(n²)
Show answer
C. O(1) — Dictionary is a hash table: the key's hash points straight to its bucket, so lookups are constant time on average.
What happens when this runs?
var d = new Dictionary<string, int> { ["a"] = 1 }; Console.WriteLine(d["b"]);- A. Prints 0
- B. Prints nothing
- C. Throws KeyNotFoundException
- D. Prints null
Show answer
C. Throws KeyNotFoundException — The indexer throws when the key is missing. Use d.TryGetValue("b", out var v) or d.GetValueOrDefault("b").
How do IEnumerable and IEnumerator relate?
- A. They are the same interface
- B. IEnumerable provides GetEnumerator(); IEnumerator does the stepping with MoveNext() and Current
- C. IEnumerator is for arrays only
- D. IEnumerable can only be used with LINQ
Show answer
B. IEnumerable provides GetEnumerator(); IEnumerator does the stepping with MoveNext() and Current — foreach calls GetEnumerator() on the IEnumerable, then MoveNext()/Current on the IEnumerator until the end.
What does this print?
class Config { static Config() { Console.Write("S"); } public Config() { Console.Write("I"); } } new Config(); new Config();- A. SISI
- B. SII
- C. II
- D. ISI
Show answer
B. SII — The static constructor runs once, before the first use of the class. The instance constructor runs for every new object.
Why make a constructor private?
- A. To make the class faster
- B. To stop code outside the class creating instances — e.g. singletons or static helper classes
- C. To allow inheritance
- D. Private constructors aren't allowed
Show answer
B. To stop code outside the class creating instances — e.g. singletons or static helper classes — With a private constructor, only the class itself can create instances, for example through a static Instance property.
Which is true about a static constructor?
- A. It can take parameters
- B. It can't have parameters or an access modifier, and runs at most once
- C. It must be public
- D. You call it with new
Show answer
B. It can't have parameters or an access modifier, and runs at most once — The runtime calls it automatically, so you can't pass arguments or choose its visibility.
What does this print?
void Inc(ref int x) => x++; int n = 5; Inc(ref n); Console.WriteLine(n);- A. 5
- B. 6
- C. 0
- D. Compile error
Show answer
B. 6 — ref passes the variable itself, so x++ changes n.
Why doesn't this compile?
bool TryGet(out int value) { return false; }- A. bool can't be returned
- B. An out parameter must be assigned before the method returns
- C. out needs ref
- D. Methods can't start with Try
Show answer
B. An out parameter must be assigned before the method returns — out means the method promises to set the value. Assign it (e.g. value = 0;) on every path.
What is a clean way to return two values from a method?
- A. Global variables
- B. A tuple, e.g. (int count, string name)
- C. Two return statements
- D. It isn't possible
Show answer
B. A tuple, e.g. (int count, string name) — Tuples (or out parameters, or a small record) let a method return several values: return (5, "Ali");
What does this print?
void Greet(string name, string greeting = "Hello") => Console.WriteLine($"{greeting}, {name}"); Greet(greeting: "Hi", name: "Sara");- A. Hello, Sara
- B. Hi, Sara
- C. Sara, Hi
- D. Compile error
Show answer
B. Hi, Sara — Named arguments can be passed in any order, and the explicit greeting replaces the default value.
How do you write an extension method?
- A. Inherit from the class
- B. A static method in a static class, with this before the first parameter
- C. Use the partial keyword
- D. Add [Extension] to any method
Show answer
B. A static method in a static class, with this before the first parameter — public static string Shout(this string s) in a static class lets you call "hi".Shout() as if it were a string method.
What does this print?
static class StringExt { public static string Shout(this string s) => s.ToUpper() + "!"; } Console.WriteLine("hey".Shout());- A. hey!
- B. HEY!
- C. HEY
- D. Compile error
Show answer
B. HEY! — The extension method is called on the string "hey": ToUpper() gives "HEY", plus "!".
What does this print?
Action a = () => Console.Write("1"); a += () => Console.Write("2"); a += () => Console.Write("3"); a -= () => Console.Write("2"); a();- A. 13
- B. 123
- C. 12
- D. Nothing
Show answer
B. 123 — Each lambda is a different delegate. The -= removes nothing because the new lambda doesn't equal the one that was added, so all three run. Keep a reference to a handler if you need to remove it.
What does the event keyword add on top of a delegate field?
- A. Nothing
- B. Outside code can only subscribe (+=) and unsubscribe (-=); only the owning class can raise it
- C. Events run on a new thread
- D. Events can't have parameters
Show answer
B. Outside code can only subscribe (+=) and unsubscribe (-=); only the owning class can raise it — A public delegate field could be invoked or overwritten by anyone. event protects it so only the class raises it.
What does var do?
- A. Makes the variable dynamic
- B. Lets the compiler infer the type — the variable is still strongly typed
- C. Declares a constant
- D. Allows changing the type later
Show answer
B. Lets the compiler infer the type — the variable is still strongly typed — var x = 5; is exactly int x = 5;. The type is fixed at compile time; only the spelling is shorter.
How is dynamic different from var?
- A. They're the same
- B. dynamic skips compile-time type checks and resolves members at run time
- C. var is checked at run time
- D. dynamic is faster
Show answer
B. dynamic skips compile-time type checks and resolves members at run time — With dynamic, typos in member names compile fine and fail at run time. Use it rarely, e.g. for COM or JSON interop.
What does this print?
object o = "text"; string? s = o as string; int? n = o as int?; Console.WriteLine($"{s} {n == null}");- A. text False
- B. text True
- C. Throws InvalidCastException
- D. True
Show answer
B. text True — as returns null instead of throwing when the cast fails. o is a string, so s is "text" and n is null.
What does this print?
enum Status { Pending, Active = 5, Closed } Console.WriteLine((int)Status.Closed);- A. 2
- B. 5
- C. 6
- D. 0
Show answer
C. 6 — Values continue from the previous member: Pending = 0, Active = 5, so Closed = 6.
What does this print?
IEnumerable<int> Evens() { for (int i = 0; i < 10; i += 2) yield return i; } Console.WriteLine(string.Join(",", Evens().Take(3)));- A. 0,2,4
- B. 2,4,6
- C. 0,2,4,6,8
- D. 0,1,2
Show answer
A. 0,2,4 — yield return produces values lazily. Take(3) stops after the first three: 0, 2, 4.
C# has two kinds of using. What are they?
- A. Both import namespaces
- B. The using directive imports a namespace; the using statement disposes an object at the end of a block
- C. Both dispose objects
- D. using only works with files
Show answer
B. The using directive imports a namespace; the using statement disposes an object at the end of a block — using System.Text; at the top imports names. using (var conn = new SqlConnection(...)) { } disposes the connection automatically.
For classes, how do == and Equals() differ by default?
- A. Both compare values
- B. == compares references unless the type overloads it; Equals can be overridden to compare values
- C. Equals is faster
- D. == throws on null
Show answer
B. == compares references unless the type overloads it; Equals can be overridden to compare values — string overloads == to compare text. For your own classes, override Equals/GetHashCode (or use records) for value equality.
Which is true about a static class?
- A. You can create instances of it
- B. It can't be instantiated or inherited and contains only static members
- C. It can implement interfaces
- D. It must be sealed and abstract by hand
Show answer
B. It can't be instantiated or inherited and contains only static members — Static classes such as Math group helper methods. The compiler blocks new and inheritance.
What does the partial keyword allow?
- A. Partial methods only
- B. Splitting one class across several files
- C. Hiding a class
- D. Inheriting from two classes
Show answer
B. Splitting one class across several files — The compiler merges all parts into one class. It's used a lot for generated code, e.g. designer files.
What does this print?
string? name = null; Console.WriteLine(name ?? "Guest"); Console.WriteLine(name?.Length ?? 0);- A. Guest 0
- B. null 0
- C. Guest null
- D. Throws NullReferenceException
Show answer
A. Guest 0 — ?? uses the right side when the left is null. ?. returns null instead of throwing, and ?? 0 turns that into 0.
What does this print?
var nums = new List<int> { 1, 3, 5 }; Console.WriteLine(nums.FirstOrDefault(n => n % 2 == 0));- A. 1
- B. Throws InvalidOperationException
- C. 0
- D. null
Show answer
C. 0 — No even number exists, so FirstOrDefault returns the default for int, which is 0. First() would throw.
What happens when this runs?
var nums = new List<int>(); var first = nums.First();- A. first is 0
- B. first is null
- C. InvalidOperationException: sequence contains no elements
- D. Compile error
Show answer
C. InvalidOperationException: sequence contains no elements — First() requires at least one element. Use FirstOrDefault() when the list might be empty.
What does this print?
var words = new[] { "pear", "fig", "apple" }; var r = words .Where(w => w.Length > 3) .OrderBy(w => w) .Select(w => w[0]); Console.WriteLine(string.Concat(r));- A. pa
- B. ap
- C. afp
- D. pfa
Show answer
B. ap — Where keeps pear and apple, OrderBy sorts them (apple, pear) and Select takes the first letters: a, p.
What does this print?
var nums = new[] { 1, 2, 3, 4, 5, 6 }; Console.WriteLine(nums.GroupBy(n => n % 3).Count());- A. 6
- B. 2
- C. 3
- D. 1
Show answer
C. 3 — n % 3 gives remainders 1, 2, 0, 1, 2, 0 — three distinct keys, so three groups.
What is a lambda expression?
- A. A type of loop
- B. A short anonymous function, e.g. x => x * 2
- C. A class
- D. A database query
Show answer
B. A short anonymous function, e.g. x => x * 2 — Lambdas are inline functions, used everywhere in LINQ: nums.Where(n => n > 3).
What does this print?
var nums = new[] { 2, 2, 3, 3, 3 }; Console.WriteLine(nums.Distinct().Sum());- A. 13
- B. 5
- C. 2
- D. 3
Show answer
B. 5 — Distinct() leaves 2 and 3, and their sum is 5.
What is the main advantage of generics like List<T>?
- A. They're faster to type
- B. Type safety without casting or boxing
- C. They allow multiple inheritance
- D. They only work with strings
Show answer
B. Type safety without casting or boxing — List<int> stores ints directly — no object casts, no boxing, and type errors are caught at compile time (unlike the old ArrayList).
What is the difference between ref and out parameters?
- A. None
- B. ref needs the variable set before the call; out must be assigned inside the method
- C. out is read-only
- D. ref only works with classes
Show answer
B. ref needs the variable set before the call; out must be assigned inside the method — int.TryParse(text, out var n) is the classic out example.
What does this print?
void AddOne(int x) { x++; } void AddOneRef(ref int x) { x++; } int a = 5, b = 5; AddOne(a); AddOneRef(ref b); Console.WriteLine($"{a} {b}");- A. 6 6
- B. 5 6
- C. 5 5
- D. 6 5
Show answer
B. 5 6 — a is passed by value (a copy); b is passed by reference, so the change sticks.
What does the params keyword allow?
- A. Optional parameters
- B. Passing a variable number of arguments, e.g. Sum(1, 2, 3)
- C. Named parameters
- D. Generic parameters
Show answer
B. Passing a variable number of arguments, e.g. Sum(1, 2, 3) — int Sum(params int[] nums) can be called with any number of ints, or an array.
What does this print?
string Greet(string name, string greeting = "Hello") => $"{greeting}, {name}"; Console.WriteLine(Greet(greeting: "Salam", name: "Ali"));- A. Hello, Ali
- B. Salam, Ali
- C. Ali, Salam
- D. Compile error
Show answer
B. Salam, Ali — Named arguments can be passed in any order.
What is a record in C#?
- A. A database row
- B. A type with value-based equality, a readable ToString and easy copies with with-expressions
- C. A static class
- D. An enum
Show answer
B. A type with value-based equality, a readable ToString and easy copies with with-expressions — record Point(int X, int Y); — two Points with the same X and Y are equal.
What does this print?
record Point(int X, int Y); var a = new Point(1, 2); var b = a with { Y = 5 }; Console.WriteLine($"{a == new Point(1, 2)} {b}");- A. False Point { X = 1, Y = 5 }
- B. True Point { X = 1, Y = 5 }
- C. True Point
- D. Compile error
Show answer
B. True Point { X = 1, Y = 5 } — Records compare by value, and their ToString lists the properties.
What do nullable reference types (string?) add?
- A. Strings can now be null for the first time
- B. Compiler warnings that help you avoid NullReferenceException
- C. Runtime null checks
- D. Faster strings
Show answer
B. Compiler warnings that help you avoid NullReferenceException — With <Nullable>enable</Nullable>, string means "should not be null" and string? means "may be null".
What does this print?
string? name = null; Console.WriteLine(name?.Length ?? -1);- A. 0
- B. -1
- C. null
- D. NullReferenceException
Show answer
B. -1 — ?. returns null instead of throwing, and ?? provides the fallback value.
What does this print?
string Describe(int n) => n switch { 0 => "zero", < 0 => "negative", > 100 => "big", _ => "normal" }; Console.WriteLine(Describe(250));- A. normal
- B. big
- C. zero
- D. Compile error
Show answer
B. big — Switch expressions with relational patterns test cases in order; 250 matches > 100.
What does yield return do?
- A. Ends the method
- B. Produces items one at a time from an iterator, only when the caller asks for the next one
- C. Returns a list
- D. Starts a thread
Show answer
B. Produces items one at a time from an iterator, only when the caller asks for the next one — The method's code runs lazily as the caller enumerates — handy for large or endless sequences.
What does this print?
var nums = new List<int> { 1, 2, 3 }; var query = nums.Where(n => n > 1); nums.Add(4); Console.WriteLine(query.Count());- A. 2
- B. 3
- C. 4
- D. 1
Show answer
B. 3 — LINQ uses deferred execution: the filter runs when Count() is called, after 4 was added.
What does a generic constraint like where T : class, new() mean?
- A. T must be a string
- B. T must be a reference type with a public parameterless constructor
- C. T must be a struct
- D. T can be anything
Show answer
B. T must be a reference type with a public parameterless constructor — Constraints let the method use features (like new T()) the compiler can't assume otherwise.
Why can IEnumerable<string> be assigned to IEnumerable<object>?
- A. It can't
- B. IEnumerable<out T> is covariant — it only returns T, so it's safe
- C. Strings are objects, so all generics allow it
- D. Boxing
Show answer
B. IEnumerable<out T> is covariant — it only returns T, so it's safe — List<string> to List<object> isn't allowed, because List also accepts items (it's invariant).
What is an enum?
- A. A list type
- B. A set of named constants, like OrderStatus.Pending or OrderStatus.Paid
- C. A collection of objects
- D. A class with methods
Show answer
B. A set of named constants, like OrderStatus.Pending or OrderStatus.Paid — Enums are backed by integers by default and make code more readable than magic numbers.
What does this print?
[Flags] enum Perm { None = 0, Read = 1, Write = 2, Delete = 4 } var p = Perm.Read | Perm.Write; Console.WriteLine($"{p} {p.HasFlag(Perm.Delete)}");- A. 3 False
- B. Read, Write False
- C. Read True
- D. Write False
Show answer
B. Read, Write False — [Flags] enums combine with | and print the names of the set flags.
What is an indexer?
- A. A database index
- B. A property that lets objects be accessed with [ ], like collection[i]
- C. A loop counter
- D. A sorting method
Show answer
B. A property that lets objects be accessed with [ ], like collection[i] — public string this[int i] => _items[i];
What is operator overloading?
- A. Using too many operators
- B. Defining what operators like + or == mean for your own types
- C. Changing operator precedence
- D. Calling methods with operators
Show answer
B. Defining what operators like + or == mean for your own types — public static Money operator +(Money a, Money b) => new(a.Amount + b.Amount);
What is the difference between a struct and a class when you assign one variable to another?
- A. None
- B. A struct is copied (value); a class copies only the reference, so both variables point to one object
- C. Classes are copied
- D. Structs can't be assigned
Show answer
B. A struct is copied (value); a class copies only the reference, so both variables point to one object — Keep structs small and immutable to avoid confusing copies.
What are Span<T> and Memory<T> for?
- A. UI layouts
- B. Working with slices of arrays, strings or buffers without allocating copies
- C. Threading
- D. Database access
Show answer
B. Working with slices of arrays, strings or buffers without allocating copies — text.AsSpan(0, 5) views part of a string without creating a new one — great for parsing hot paths.
What does the init accessor do?
- A. Runs on startup
- B. Lets a property be set only during object creation, then makes it read-only
- C. Initialises static fields
- D. Calls the constructor
Show answer
B. Lets a property be set only during object creation, then makes it read-only — public string Name { get; init; } — set it in new Person { Name = "Ali" } but not later.
What does the required modifier (C# 11) on a property do?
- A. Makes it non-null at run time
- B. Forces callers to set it in the object initializer, or the code won't compile
- C. Adds validation attributes
- D. Makes it static
Show answer
B. Forces callers to set it in the object initializer, or the code won't compile — public required string Email { get; init; } catches forgotten fields at compile time.
What is wrong with this method?
public async void SaveAsync() { await _db.SaveChangesAsync(); }- A. Nothing
- B. async void can't be awaited and its exceptions can crash the app — return Task instead
- C. SaveChangesAsync isn't awaitable
- D. It needs ConfigureAwait
Show answer
B. async void can't be awaited and its exceptions can crash the app — return Task instead — Use async void only for event handlers; everything else should return Task or Task<T>.
What is a local function?
- A. A function in another file
- B. A method declared inside another method, visible only there
- C. A static method
- D. A lambda stored in a field
Show answer
B. A method declared inside another method, visible only there — Good for helper logic used only by one method, such as a recursive helper.
What does this print?
var words = new[] { "apple", "kiwi", "banana", "fig" }; var result = words.OrderBy(w => w.Length).ThenBy(w => w).First(); Console.WriteLine(result);- A. apple
- B. fig
- C. kiwi
- D. banana
Show answer
B. fig — Sorted by length first: fig (3) is the shortest.
More subjects
Need software for your business instead? I'm an AI automation & full-stack developer — see what I build.