C# Fundamentals Interview Questions for .NET Full Stack
25 C# Fundamentals questions with answers for .net full stack roles — 11 easy, 10 medium, 4 hard.
About C# Fundamentals
The C# language that every .NET interview starts with: value and reference types, strings, nullability, records, pattern matching, exceptions, memory management and the CLR. Interviewers test whether you understand what happens under the hood, such as boxing, garbage collection and how modern features like primary constructors and Span reduce boilerplate and allocations.
Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
What is the difference between .NET Framework, .NET Core and modern .NET?
.NET Framework is the original Windows-only runtime, now in maintenance mode at version 4.8.1. .NET Core was the cross-platform, open-source rewrite. From .NET 5 onwards the name became just .NET, and it runs on Windows, Linux and macOS. In 2026, .NET 10 is the current LTS release. New projects should use modern .NET; Framework is kept only for legacy apps such as old Web Forms or WCF services.
The Common Language Runtime is the execution engine of .NET. It loads compiled IL code, converts it to machine code with the JIT compiler, manages memory through the garbage collector, enforces type safety, handles exceptions and manages threads. Because every .NET language compiles to the same IL, C#, F# and VB.NET code can run on the same CLR and call each other.
Value types such as int, double, bool, enums and structs hold their data directly, and assigning one copies the value. Reference types such as classes, arrays, strings and delegates hold a reference to an object on the managed heap, so assigning copies only the reference. Changing a copied struct does not affect the original, but changing an object through a copied reference changes what both variables see.
Boxing converts a value type to object or an interface type by wrapping it in a heap object, for example object o = 42. Unboxing extracts the value back with an explicit cast, such as int n = (int)o. Both cost allocations and CPU time, and repeated boxing in loops increases garbage collection pressure. Generic collections like List<int> avoid boxing, which is one reason ArrayList is no longer used.
05
When should you use StringBuilder instead of string?
Strings in C# are immutable, so every concatenation creates a new string object and copies the old content. In a loop that appends thousands of times, this creates heavy allocations. StringBuilder keeps a resizable internal buffer and appends in place, so it is much faster for repeated changes. For two or three concatenations or interpolation in a single statement, a normal string is simpler and fine.
06
Write an extension method that checks whether a string is a valid Indian mobile number.
public static class StringExtensions
{
public static bool IsIndianMobile(this string? value) =>
value is not null &&
System.Text.RegularExpressions.Regex.IsMatch(value, @"^[6-9]\d{9}$");
}
// usage
bool ok = "9876543210".IsIndianMobile();
Extension methods are static methods in a static class whose first parameter uses this, so they appear like instance methods.
07
What is the difference between var, dynamic and object?
var is implicitly typed: the compiler infers the real type at compile time, so it is fully type-safe. object is the base type of everything; you need casts to use specific members, and value types get boxed. dynamic skips compile-time checking and resolves members at runtime, so typos fail only when the code runs. Use var for readability, object rarely, and dynamic only for COM interop or truly dynamic data.
08
A report builder concatenates 50,000 rows into one string with += and takes several seconds. What do you change?
Each += creates a new string and copies everything built so far, so the cost grows quadratically. Replace it with a StringBuilder, ideally created with an estimated capacity, and call Append or AppendLine in the loop, then ToString once at the end. For very large output, write directly to a StreamWriter or the response stream instead of building the whole string in memory.
09
Write a C# method to reverse a string without using Array.Reverse or LINQ.
static string ReverseText(string input)
{
char[] chars = input.ToCharArray();
int left = 0, right = chars.Length - 1;
while (left < right)
{
(chars[left], chars[right]) = (chars[right], chars[left]);
left++;
right--;
}
return new string(chars);
}
Two pointers swap from both ends, giving O(n) time and O(n) space for the char array.
10
Tell me about a time you had to learn a new C# or .NET feature quickly.
In my final-year project (Situation) our team needed async file uploads, but I only knew synchronous code. My task was to build the upload API within a week. I read the official async/await docs, built a small console demo, then refactored our controller to use async methods and IFormFile streaming. The result was uploads that no longer blocked requests, and I shared a short note with my team.
11
Why do you want to work as a .NET full stack developer?
I enjoy building complete features, from database to screen, and .NET lets me do that with one strong, typed language on the back end. It is widely used by IT services firms, banks and product companies in India, so there are steady opportunities. I have built projects with ASP.NET Core and React, and I like that the platform is open source, cross-platform and keeps improving every year.
12
What is the difference between const, readonly and static readonly?
const is a compile-time constant, implicitly static, and its value is copied into calling assemblies, so changing it requires recompiling them. readonly fields are set at declaration or in the constructor and can differ per instance. static readonly is set once per type at runtime, so it can hold values like DateTime.Now or a new object. Use const only for values that will never change, such as Math.PI.
ref passes a variable by reference; it must be initialised before the call and the method can read and change it. out also passes by reference but need not be initialised, and the method must assign it before returning, as in int.TryParse. in passes by reference as read-only, which avoids copying large structs while preventing changes. Overusing ref and out makes code harder to read, so tuples are often cleaner.
14
What are nullable value types and nullable reference types?
Nullable value types like int? wrap a struct so it can hold null, with HasValue and Value properties. Nullable reference types, enabled by <Nullable>enable</Nullable>, are a compile-time feature: string means non-null and string? means may be null, and the compiler warns when you dereference a possible null. They do not change runtime behaviour but catch many NullReferenceException bugs before deployment.
15
Show how to implement IDisposable and use the using statement.
public class FileLogger : IDisposable
{
private readonly StreamWriter _writer = new("log.txt");
public void Log(string msg) => _writer.WriteLine(msg);
public void Dispose() => _writer.Dispose();
}
// using declaration disposes at end of scope
using var logger = new FileLogger();
logger.Log("Started");
Dispose releases unmanaged resources such as file handles and connections deterministically instead of waiting for the GC.
16
What is the difference between == and Equals() in C#?
For reference types, == by default checks reference equality, meaning both variables point to the same object, while Equals can be overridden to compare content. String overrides both, so == compares text. For value types, Equals compares field values. Records generate value-based equality automatically. When you override Equals, also override GetHashCode so objects behave correctly in dictionaries and hash sets.
17
What are record types and when would you use them?
Records are reference types (or record struct for value types) designed for immutable data. The compiler generates value-based equality, a readable ToString, a deconstructor and support for with-expressions that create a modified copy. A positional record is one line: public record Order(int Id, decimal Total). They suit DTOs, API responses, events and value objects, but not EF Core entities that need change tracking by identity.
18
You are designing a type to hold a 2D point used millions of times in a calculation. Struct or class?
A struct is a good fit because the point is small, logically a single value and created in huge numbers. Structs avoid heap allocation and GC pressure when stored in arrays or locals. Make it a readonly struct so it is immutable and avoids defensive copies. Choose a class instead if the type is large, needs inheritance, or is frequently boxed through interfaces, since copying and boxing remove the benefit.
19
Write a switch expression using pattern matching to calculate shipping cost.
throw rethrows the current exception and preserves the original stack trace, so logs show where the error really started. throw ex resets the stack trace to the catch block, hiding the real source. Always use throw when rethrowing. If you need more context, wrap it: throw new OrderException("Payment failed", ex), which keeps the original as InnerException. Also avoid catching Exception unless you log and rethrow.
21
Show a class using a primary constructor with dependency injection.
public class OrderService(IOrderRepository repo, ILogger<OrderService> logger)
{
public async Task<Order?> GetAsync(int id)
{
logger.LogInformation("Fetching order {Id}", id);
return await repo.FindAsync(id);
}
}
Primary constructors on classes arrived in C# 12. Parameters are captured and usable in all members, removing boilerplate fields. They are not readonly, so assign to a readonly field if immutability matters.
22
How does garbage collection work in .NET and what are generations?
The GC automatically frees objects that are no longer reachable from roots such as static fields, locals and CPU registers. The heap is split into generations: Gen 0 for new short-lived objects, Gen 1 as a buffer, and Gen 2 for long-lived objects. Most objects die young, so Gen 0 collections are frequent and cheap. Objects over 85,000 bytes go to the Large Object Heap, which is collected with Gen 2.
23
What are Span<T> and Memory<T> and why do they matter for performance?
Span<T> is a ref struct that represents a contiguous slice of memory, such as part of an array, a string or stack memory, without copying it. Slicing a span is free, which makes parsing much faster with zero allocations. Because it is stack-only, it cannot be stored in fields or used across await. Memory<T> is the heap-storable version for async code. ASP.NET Core and System.Text.Json use them heavily.
24
A .NET API's memory keeps growing in production until the pod restarts. How do you investigate?
First confirm with metrics using dotnet-counters: watch GC heap size, Gen 2 count and LOH size. Then capture a heap dump with dotnet-gcdump or dotnet-dump and compare two dumps over time to find which object types keep growing and what roots hold them. Common causes are static caches without expiry, event handlers never unsubscribed, undisposed HttpClient or DbContext, and singletons capturing scoped services. Fix the root, then load test.
25
What is the difference between JIT compilation and Native AOT in .NET?
With JIT, the app ships as IL and the runtime compiles methods to machine code when first called; tiered compilation later recompiles hot methods with better optimisation. Native AOT compiles everything ahead of time into a single native executable, giving very fast startup and lower memory, which suits containers and serverless. The trade-off is limited reflection and dynamic code generation, so some libraries need source generators to work.
Frequently asked questions
How important is C# Fundamentals in .NET Full Stack interviews?
The C# language that every .NET interview starts with: value and reference types, strings, nullability, records, pattern matching, exceptions, memory management and the CLR. Interviewers test whether you understand what happens under the hood, such as boxing, garbage collection and how modern features like primary constructors and Span reduce boilerplate and allocations.
How should I use the C# Fundamentals sheet?
Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.