C# Interview Questions for 5 years Experience
When you switch between companies, you are expected to know about the work you do in-depth, and when you are a 5+ experienced software developer in C#, you can expect no less. Giving interviews with 5+ years of experience needs you to prove your calibre and why you are a skilled master in C#, thereby allowing companies to measure your depth of knowledge and experience through all means possible.
We have curated this article with the best of questions to help you prepare for interviews in C#. In this article, you will get to learn about some of the most asked questions around theoretical topics, practical implementations, and some scenario-based questions in C#. Here, we will cover a wide range of important C# topics that are the applications of variables, collections, polymorphism, strings, data types, and threads.
C# Interview Questions for Experienced (5+ years)
1. What is the use of the method "hiding" in inheritance?
Method hiding or Method shadowing is used to hide the implementation of the base class method under the shadow of the child class method, with the help of a new keyword.
This is done to clear the ambiguity when the child class has a method with the same name as that of the base class and hence helps in abstraction.
// C# program to illustrate the
// concept of method hiding
using System;
// Base Class
public class Parent {
public void member()
{
Console.WriteLine("Parent method");
}
}
// Derived Class
public class Child : Parent {
// Reimplement the method of the base class
// Using new keyword
// It hides the method of the base class
public new void member()
{
Console.WriteLine("Child method");
}
}
// Driver Class
class DriverClass {
// Main method
static public void Main()
{
// Creating the object of the derived class
Child obj = new Child();
// Access the method of derived class
obj.member();
}
}
2. What is Serialization in C#?
When we want to store any object to a memory, a database, or a file, it needs a special process known as Serialization.
Serialization is the process of converting an object into a different form to store it on to a file, database, or memory. The purpose of Serialization is to transfer the object and its state across the network and recreate it successfully when needed.
The reverse of Serialization is known as Deserialization.
There are many types of serialization in C#, such as:
- Binary serialization: To save the state of the object in binary format. This is done using classes defined in the System.Runtime.Serialization namespace.
- Soap Serialization: To save the state of the object in binary format, with the use of network-related communication.
- XML Serialization: To save the state of the object in XML format. This is done using classes defined in the System.Xml.Serialization namespace.
- JSON Serialization: To save the state of the object in JSON format. This is done using classes defined in the System.Text.Json namespace.
There are some third-party serialization formats as well that are supported in C#, such as MessagePack (msgpack).
Conclusion:
If you are planning to go for an interview in C# with 5+ years of experience, then you will need to be ready for some aggressive, in-depth, and out-of-the-box questions. However, with proper knowledge, brush up on your experience and expertise, and proper preparation, you can easily crack any interview.
Useful Resources:
3. What are sealed classes in C#?
If we want to prevent any class from being inherited, it can be done with the help of a sealed keyword. So using a sealed keyword, a class denies the ability to create any child entity of this class, thereby calling itself a sealed class. If by mistake, a child of a sealed class is tried to be made, a compile-time error will occur.
using System;
// Sealed class
sealed class SealedClass
{
public int Add(int x, int y)
{
return x + y;
}
}
class Class1: SealedClass
{
static void Main(string[] args)
{
SealedClass sealedCls = new SealedClass();
int total = sealedCls.Add(4, 5);
Console.WriteLine("Total = " + total.ToString());
}
}
Compilation error:
prog.cs(12,7): error CS0509: `Class1': cannot derive from sealed type `SealedClass'
prog.cs(4,14): (Location of the symbol related to previous error)
Compilation failed: 1 error(s), 0 warnings
4. What is the lock statement in C#?
During multi-threading, when a thread is inside a critical section, it must not be removed or stopped until it is completed. To implement this feature, lock statements are used in C# which prevents other threads from entering a locked code (currently in the critical section), until the object is released.
static object obj = new object();
public static void LockDemo()
{
lock(obj)
{
Console.WriteLine("Demonstrating use of Lock statement in C#");
}
}
5. Show an example of how the Mutex synchronization mechanism works.
This example shows how a local Mutex object is used to synchronize access to a protected resource.
using System;
using System.Collections;
using System.Threading;
namespace MutexDemo
{
class MutexDemoClass
{
private static Mutex mutex = new Mutex();
private const int countOfHits = 1;
private const int countOfThreads = 3;
private static void ThreadProcess()
{
for (int i = 0; i < countOfHits; i++)
{
showMutexDemo();
}
}
private static void showMutexDemo()
{
// Wait until it is safe to enter.
mutex.WaitOne();
Console.WriteLine("{0} has got the access of resource",
Thread.CurrentThread.Name);
// Code to access the resource mutually exclusively
// Wait until it is safe to enter.
Thread.Sleep(100);
Console.WriteLine("{0}'s access of the resource has been revoked",
Thread.CurrentThread.Name);
// Once the work is done, release the resource from Mutex
mutex.ReleaseMutex();
}
// Driver code
static void Main(string[] args)
{
for (int i = 0; i < countOfThreads; i++)
{
Thread thread = new Thread(new ThreadStart(ThreadProcess));
thread.Name = String.Format("Thread{0}", i + 1);
thread.Start();
}
}
}
}
The above code is a simple example to show how Mutex locks a resource and only that thread can release the Mutex.
Thread1 has got the access of resource
Thread1's access of the resource has been revoked
Thread2 has got the access of resource
Thread2's access of the resource has been revoked
Thread2 has got the access of resource
Thread3's access of the resource has been revoked
Learn via our Video Courses
6. What is Mutex and how is it different from other Synchronization mechanisms?
MuTex refers to Mutual Exclusion and as the name suggests, Mutex works on the mutual exclusion principle to lock out any other thread requesting for a resource whose access is already given to some thread. Mutex acts as a flag mechanism that prevents any second thread from accessing a resource, except for the thread which is currently working on it.
Unlike other synchronization mechanisms in C#, such as Auto Reset Event which can give the exclusive access of a resource to any thread that calls the set() method, Mutex remembers the thread that gets the resource access, and only that same thread can reset it, thereby giving the true mutual exclusion synchronization. If the thread differs, a mutex exception is thrown.
7. What is AutoResetEvent and how is it different from ManualResetEvent?
AutoResetEvent is used to unlock a single thread when multiple threads are in a waiting blocked state, whereas ManualResetEvent is used to unlock multiple threads at once during similar instances.
AutoResetEvent also calls the Reset() method by itself to unblock the thread under consideration, whereas while using ManualResetEvent, the Reset() method has to be called manually after the use of set() method.
8. What are Interlocked functions?
Shared variables in C# are not thread-safe. It means that any operation on a variable can be corrupted due to multiple threads. To prevent these dirty reads, C# allows the use of interlocked functions to change the value of shared variables in multithreading code.
Interlocked functions only support int, long, double and float data types, as shown by some of the examples below:
1) Add(ref int address1, int value): Interlocked function to add a value into an int variable safely.
2) Increment(ref int address1): Interlocked function to increment value of an int variable safely by 1.
3) Decrement(ref int address1): Interlocked function to decrement value of an int variable safely by 1.
4) Exchange(ref int address1, int value): Interlocked function to replace the value of an int variable safely.
5) CompareExchange(ref int address1, int newValue, int toBeValue): Interlocked function to replace the value of an int variable safely only if the existing value is equal to passed toBeValue.
9. What is enum in C#?
Enum is a primitive data type in C# used to define numeric constants in the .NET framework. Starting from 0, all the elements of the enum are given constant values, each increasing by 1.
For example, if we declare an enum for days of the week, the first element (Sunday) will get the value 0, the next element (Monday) will get the value 1, and so on till Saturday, which will get the value 6.
enum daysOfWeek { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
To access any element, all you need to do is just pass the value of the element alongside enum’s variable, such as:
daysOfWeek[5]; // Will give the value Friday
10. What is the difference between dispose() and finalize() methods in C#?
Both dispose() and finalize() methods are used for unallocating and freeing up resources but:
- dispose() method is called explicitly by the user, whereas finalize() method is called the system’s garbage collector at the end of execution.
- dispose() method is defined in the IDisposable interface, whereas the finalize() method is defined in the Object class.
- dispose() method is a part of the developer’s code, whereas finalize() method is a system-defined default method and not a part of the developer’s code.
BASIS FOR COMPARISON | DISPOSE( ) | FINALIZE( ) |
---|---|---|
Definition | dispose() method is defined in IDisposable interface. | finalize() method is defined in java.lang.object class. |
Syntax |
|
|
Invoked | dispose() method is invoked by the user. | finalize() method is invoked by the garbage collector. |
Purpose | dispose() method is used to free unmanaged resources upon invoking. | finalize() method is used to free the unmanaged resources when invoked by the garbage collector. |
Implementation | dispose() method is implemented whenever there is a close( ) method. | Unlike dispose(), the finalize() method is implemented for freeing up unmanaged resources. |
Access Specifier | dispose() method is declared as public. | finalize() method is declared as private. |
Performance | dispose() method happens instantly and hence is faster. | finalize() method is slower in comparison with dispose() method and can affect the performance. |
11. What is the difference between a struct and a class in C#?
Struct | Class |
---|---|
Structs are value-type entities stored in stack memory. | Class is a reference type entity stored in heap memory. |
Allocation and de-allocation of Structs are cheaper when the size of the Structure is small. | Allocation and de-allocation of Classes are costlier when the size of the class is small. |
Allocation and de-allocation of Structs are costlier as compared to classes when the size of a struct is large. | Allocation and de-allocation of Classes are cheaper as compared to Structs when the size of the class is large. |
Structs can contain limited kind of entities like variables, structs, etc, and hence is used to create smaller codes. | Classes can contain all kind of entities like variables, functions, constructors, structs, etc, and hence is used to create large codes efficiently. |
Structures are not allowed to contain parameterless constructors or destructors, but only parameterized constructors and static constructors. | Classes can contain any kind of constructors or destructors. |
An instance of a struct can be created by using the new keyword, as well as without using a new keyword. | To create an instance of a class, a new keyword is used. |
A Struct cannot implement Inheritance and hence cannot inherit another struct or class. | A Class can implement Inheritance and can inherit from another class. |
The attributes of a struct cannot be specified as protected. | The attributes of a class can be specified as protected. |
A struct can neither have a virtual method nor an abstract method. | A class can have virtual methods as well as abstract methods. |
12. How to declare a property in a class in C#?
class ABC
{
// Declare the attribute
private int id;
// Declare id’s property
public int ID
{
// read-only getter property
get { return id; }
set { id = value; }
}
}
13. How do you give a C# Autoproperty a default value?
For C# 5:
class Car()
{
public Car()
{
CarName="default car name";
}
public string CarName{get;set;}
}
For C# 6.0:
public string CarName {get;set}="default car name";
14. How to specify what version of the framework your application is targeting?
In the configuration file, just use the targetFramework
attribute to specify the version of ASP.NET that your application is targeting.
Below is the syntax used:
<?xml version=”1.0”?>
<configuration>
<system.web>
<compilation targetFramework=4.0>
</configuration>
15. What is Framework targeting in C# and what is the use of it?
Framework targeting in C# is used to mention the version of the .NET framework that the project is intended to run upon.
Framework targeting helps guarantee that the application uses only functionality that is available in the specified framework version.
16. State the uses of Reflection in C#
Reflection is the process of describing the metadata of types, methods, and fields in a code.
Some of the major use of Reflection in C#:
- Load assemblies at the given runtime
- Help to learn about the definition of entities like class, or enumeration by groups
- Get to know about fields, properties, constructors, events, and methods in a Class
- Helps to learn about the properties of entities such as their types, read-only status, etc.
- Helps in getting and setting a property’s value
- Helps to learn about an entity’s attributes.
17. What is C#?
C# is a simple, modern, general-purpose, object-oriented programming language developed by Microsoft. It is type-safe and managed language that is compiled by the Roslyn .NET compiler to generate Microsoft intermediate language (machine code).
18. What can be the output of the following program?
public class Program
{
public static void Main(string[] args)
{
var values = new List<int>() { 1, 2, 3, 4 };
var funcs = new List<Func<int>>();
foreach(var v in values)
funcs.Add( ()=>v );
foreach(var f in funcs)
Console.WriteLine(f());
}
}
The output will be:
4
4
4
4
Explanation:
The correct value of the above code will be “4 4 4 4” and not “1 2 3 4”. Let us see why.
We are creating a delegate of functions using statement
foreach(var v in values)
funcs.Add( ()=>v );
So the loop will traverse for all values as v, i.e. 1, 2, 3, till 4. Now when ()=>v is used, it means to return the latest value of variable v, and not the value when delegate was created. Therefore when the methods run, the last value assigned to v was 4, so the methods will be called using value 4 each time, and hence the output will be
“4
4
4
4”
19. What are Access Modifiers in C# And Why are they important?
As the name suggests, access modifiers are keywords that define the scope of entities in a C# code, as to which point an entity can be accessed from its point of creation.
In particular, there are 4 access modifiers in C#: public, protected, internal, and private.
20. How will you implement Encapsulation?
Encapsulation is done with the help of access modifiers in C#: public, private, protected, and default.
Scope of an element with the access specifier / Access specifiers | public | protected | internal | protected internal | private | private protected |
---|---|---|---|---|---|---|
Entire program | Yes | No | No | No | No | No |
Containing class | Yes | Yes | Yes | Yes | Yes | Yes |
Current assembly | Yes | No | Yes | Yes | No | No |
Derived types | Yes | Yes | No | Yes | No | No |
Derived types within the current assembly | Yes | Yes | Yes | Yes | No | Yes |
21. What is the need for Encapsulation?
Encapsulation is the process of binding an entity with its implementation with the aim of data hiding. It is done to hide the irrelevant details from a user, and show only the process which the user needs. By doing so, we hide the implementation details of entities and thereby help users to understand the higher-level design of the code easily, without getting bothered about the implementation details.
Encapsulation has some hidden advantages as well which make it the need of the hour for every software developer such as preventing accidental corruption, unauthorized access to entities, etc.
22. Why are strings in c# immutable?
In C# Arrays have a fixed size, which means that once an array is created of some size, it cannot be dynamically increased or decreased in size. The CLR (Common Language Runtime) in C#, stores the strings as an array of characters. So whenever we delete or add a character or characters to a string, the original arrays of characters are fixed, and hence a new array of characters is created to accommodate the change. This is known as the immutability of strings in C#.
23. What is the difference between ref and out keywords?
- ref keyword is used to pass an already initialized variable to a method as a reference type, facilitating bi-directional data passing.
Example 1:
// C# program to illustrate the concept of out parameter
using System;
class GFG {
// Main method
static public void Main()
{
// Lets declare a string
string str3 = "Scaler";
// Pass variable str3 to the method using ref keyword
initializeString(ref str3);
// Display the value str3 now
// Since initially we declared value "Scaler" in str3,
// normally below statement must print "Hello Scaler"
// But due to the use of ref keyword,
// the value will be overwritten in the initializeString() Method
// So now the value printed will be "Hello InterviewBit" instead
Console.WriteLine("Hello {0}", str3);
}
// Method in which ref parameter is passed and a value is written into this variable
public static void initializeString(ref string str1)
{
// Since ref keyword supports bi-directional data flow,
// This check statement will be validated and output will be printed
if (str1 == "Scaler") {
Console.WriteLine("Hello Scaler");
}
// Now lets try to change the value of ref parameter str1
// The value "InterviewBit" will be overwritten in reference variable str3
str1 = "InterviewBit";
}
}
The above program will generate the below output:
Hello Scaler
Hello InterviewBit
- Whereas out keyword is used to pass a variable as an empty container that can store multiple values to a method as a reference type. out keyword allows uni-directional data passing, as the container passed using out keyword doesn’t need to be initialized beforehand.
Example 2: Let’s see if and how the data flows when out keyword is used:
// C# program to illustrate the concept of out parameter
using System;
class GFG {
// Main method
static public void Main()
{
// Declaring a string variable
// Since we are going to use out parameter
// We do not need to assign any value to it
string str1;
// Pass variable str1 to the method using out keyword
// Normally it should pass the default value, but due to use of out keyword
// An empty container will be passed instead, leading to error
checkIfScaler(out str1);
// Lets try again with another value
string str2 = "Scaler";
// Pass variable str2 to the method using out keyword
// Now you must think that the value "Scaler" will be passed
// But due to use of out keyword,
// again an empty container will be passed instead, leading to error
checkIfScaler(out str2);
}
// Method in which out parameter is passed and checked
// if the current string value is Scaler or not
public static void checkIfScaler(out string str1)
{
// Check parameter value
// Since we are using out parameter, this will lead to error
// as no data is passed when into this method when out keyword is used
// This is because out keyword onlu facilitates uni-direction data transfer
if (str1 == "Scaler") {
Console.WriteLine("Hello!!Scaler");
}
}
}
The above program will generate the below error:
prog.cs(39,13): error CS0269: Use of unassigned out parameter `str1'
Example 3: Now let us try to see what happens when we initialize some value to an out parameter.
// C# program to illustrate the concept of out parameter
using System;
class GFG {
// Main method
static public void Main()
{
// Lets declare a string
string str3 = "Scaler";
// Pass variable str3 to the method using out keyword
// Now you must think that the value "Scaler" will be passed
// But due to use of out keyword,
// again an empty container will be passed instead
initializeString(out str3);
// Display the value str1 now
// Since initially we declared value "Scaler" in str3,
// normally below statement must print "Hello Scaler"
// But due to the use of out keyword,
// the value will be overwritten in the initializeString() Method
// So now the value printed will be "Hello InterviewBit" instead
Console.WriteLine("Hello {0}", str3);
}
// Method in which out parameter is passed and a value is written into this variable
public static void initializeString(out string str1)
{
// Since out keyword supports uni-directional data flow,
// the value "InterviewBit" will be written in reference variable str3
str1 = "InterviewBit";
// Check parameter value
if (str1 == "InterviewBit") {
Console.WriteLine("InterviewBit value assigned successfully");
}
}
}
The above program will generate the below output:
InterviewBit value assigned successfully
Hello InterviewBit
24. Give examples of I/O classes?
Some of the important input-output classes are:
I/O Class | Description |
---|---|
FileStream | For input-output in a file. |
BinaryReader | For reading data from a binary stream. |
BinaryWriter | For writing data in binary format. |
File | For manipulating files. |
StreamReader | For reading characters from a stream. |
StreamWriter | For writing characters into a stream. |
StringReader | For reading characters from a string buffer. |
StringWriter | For writing characters into a string buffer. |
Directory | For manipulating a directory structure. |
DirectoryInfo | For performing operations on directories. |
25. How to declare a private constructor in C#?
In C#, if you don’t specify any access specifier against a constructor, that constructor is by default specified as a public constructor by the compiler.
If you want to create a Private constructor explicitly, it can be declared in C# with the help of a private keyword placed before the constructor name in its signature, as shown below:
private constructor_name
{
// Code
}
However, to create an instance of a class with a private constructor is a tricky thing. To do so, the Singleton class is used. Singleton class is a class that has only one instance. Below is the example to create an instance of a class with a private constructor, with the help of the Singleton class.
using System;
public class SingletonDemo
{
private static string CreatedOn;
private static SingletonDemo instance = null;
private SingletonDemo()
{
CreatedOn = DateTime.Now.ToLongTimeString();
}
public static SingletonDemo getInstance()
{
if (instance == null)
{
instance = new SingletonDemo();
}
Console.WriteLine(CreatedOn);
return instance;
}
}
26. What is a namespace?
Namespace in C# can be considered as a container in which you can define classes, methods, interfaces, structures, or other child namespaces, such that classes with the same name but different namespaces won’t cause any error. In C#, namespaces are an efficient entity to organize codes for larger applications.
The major advantages of Namespace are:
- Namespaces help in effectively organizing large C# code projects.
- To use any entity in a namespace, simply use <namespace name>.<entity name>
- No two classes with the same name in a different namespace will cause any error.
27. How many types of constructors can a class have?
Like functions, a class can have any number of constructors. But unlike functions, all the constructors will have the same name, the name of the class, but different parameter signatures. In other words, you can create as many valid overloads of a constructor, as you want.
28. Which constructor is called first in C#?
Base Constructor is always called first in C#, followed by Derived class constructor.
29. Can we override a constructor?
No, in C#, it is necessary to define properly which constructor you are trying to call to instantiate a class and what arguments are being passed. So you cannot override a constructor in C#.
Example: Below example will lead to a compilation error.
// C# program to show constructor overriding is not allowed in C#
using System;
// Base class
class Parent {
Parent ()
{
Console.WriteLine("Parent constructor");
}
}
// Derived class
class Child : Parent
{
Parent()
{
Console.WriteLine("Child constructor");
}
}
// Driver Class
class GFG {
// Main Method
static void Main()
{
// Create an object of Child class
var obj = new Child();
}
}
However, you can overload a constructor in C#, for sure.
30. What is a delegate?
A delegate is a reference type entity that is used to store the reference of a method. So whenever you need to call a method, you can easily use the delegate by initializing a pointer to that method, thereby helping to implement Encapsulation.
// C# program to show the use of Delegates
using System;
namespace DelegateExample {
// Declare class "DelegateExampleClass"
class DelegateExampleClass {
// Declaring the delegates -
// "addTwoNumbers", and "substractTwoNumbers"
// The return type and parameter type of the
// delegates must be the same of the methods
public delegate void addTwoNumbers(int a, int b);
public delegate void substractTwoNumbers(int a, int b);
// Method sumOf2Nums having same return type
// and parameter type as that of delegate
public void sumOf2Nums(int a, int b)
{
Console.WriteLine("({0} + {1}) = {2}", a, b, a + b);
}
// Method differenceOf2Nums having same return type
// and parameter type as that of delegate
public void differenceOf2Nums(int a, int b)
{
Console.WriteLine("({0} - {1}) = {2}", a, b, a - b);
}
// Main Method
public static void Main(String []args)
{
// Creating object of class "DelegateExampleClass"
DelegateExampleClass obj = new DelegateExampleClass();
// creating object of delegate, name as "del_obj1"
// for method "sum" and "del_obj2" for method "subtract" &
// pass the parameter as the two methods by class object "obj"
// instantiating the delegates
// Create objects of declared Delegates and pass
// the methods of class DelegateExampleClass
// using the objects thereby implementing Encapsulation
addTwoNumbers delegateObj1 = new addTwoNumbers(obj.sumOf2Nums);
substractTwoNumbers delegateObj2 = new substractTwoNumbers(obj.differenceOf2Nums);
// Call the methods of the class DelegateExampleClass
// using the delegate objects using appropriate values
delegateObj1(50, 40);
delegateObj2(50, 40);
}
}
}
Delegates in C# are similar to function pointers in C/C++ and can be used to pass methods as arguments to other methods, chained together, or even can be used to call methods on events.
31. What is an object pool?
- An object pool is a container built to keep the most used objects for faster access and use.
- An object pool is based on the object pool design pattern in which instead of every time creating objects when needed, commonly used objects are created beforehand and kept in an easily accessible location. This is done to reduce the cost of the application as creating objects can use a lot of resources and can sometimes lead to the slowness of the .NET application.
- The objects of the pool are returned to the pool, once the use is over, thus making it efficient to reuse them. If the object is not in the pool, it is then created when needed as a normal object.
32. Differentiate between static and public?
The public access modifier in C# states the compiler that the element is accessible by any other element in the same or other class.
When a member in C# has the Static access modifier in front of it, such as static method, static variable, or static parameters, it means that the element has global access and any other element can access it using class directly. You don't need to create an instance of the class to access that element. The compiler stores the address of the method as the entry point and uses this information to begin execution before any objects are created.