// 23 Essential C# Interview Questions
C# is a powerful, object-oriented programming language that is widely used for building Windows applications, web applications, and games. As a result, C# developers are in high demand in the tech industry. If you're preparing for a C# interview, it's important to be familiar with some common C# interview questions.
In this blog post, we will cover some of the most commonly asked C# interview questions and provide you with tips on how to answer them effectively. Whether you're a beginner or an experienced C# developer, this guide will help you prepare for your next C# interview.
Looking for Freelance C# Developers? Build your product with Flexiple's top-quality talent.
Hire a C# DeveloperHire NowNo, C# throws a compile-time error if multiple catch blocks are set up for the same exception.
However, you can use multiple catch blocks for different exceptions inside a single try block.
Note: Commonly asked C# interview questionObject obj2 = 123;
int anum2 = (int)obj;
As a reference type is being converted to a value type, this type of conversion is called unboxing.
The process of doing the reverse is called boxing.
Although both the == operator and the equals() methods are used to compare two objects, the logic they use are not the same.
The == operator compares two objects based on their reference identity i.e a boolean true would be returned if both objects refer to the same object.
However, the equals() method compares two objects based on their content.
Example Code:
using System;
namespace Comparision
{
class ComparisonCode
{
static void Main(string[] args)
{
string name = "flexiple";
string myName = name;
char[] values = {'f','l','e','x','i','p','l','e'};
object myValues = new string(values);
//Comparing a name and myName with == and Equals
Console.WriteLine(name == myName);
Console.WriteLine(name.Equals(myName));
//Comparing a name and myVame with == and Equals
Console.WriteLine(name == myValues);
Console.WriteLine(name.Equals(myValues));
Console.ReadKey();
}
}
}
//Output:
//True
//True
//False
//True
Note: Commonly asked C# interview questionClasses are used widely while working with C#. It comes with 4 different types of classes.
- Static Class: Static classes contain static members, methods, and constructors. Static classes do not allow new objects to be created. Static classes are sealed, hence you cannot inherit a static class from another class.
- Partial Class: A partial class allows users to split the functionality of a class across the same file or even multiple files. During compilation, all instances are combined and treated as one. Partial classes are defined using the partial keyword. Splitting a class allows multiple developers to work with the same class simultaneously. However, keep in mind that if any instance of the class is declared sealed, abstract, or base, the whole class is declared with the same type.
- Abstract Class: Abstract classes are restricted classes that cannot be used to create objects. However, an abstract class must contain at least one abstract method. These methods do not have a body and are declared inside the class only. The abstract keyword is used to define an abstract class. The purpose of an abstract class is to provide a blueprint for derived classes and set some rules on what the derived classes must implement when they inherit an abstract class.
- Sealed Class: Sealed classes restrict users from using inheritance, preventing the user from inheriting another class from it. Sealed classes are defined using the sealed keyword. Given the inheritance attribute has been taken away, sealed classes work best when used with a class inheriting static members.
Method overloading is the process of redefining a function one or more times with the same name to perform different operations based on the parameters.
Method overloading is a common way of implementing polymorphism. C# distingues the methods based on their signature.
Methods can be overloaded in the following ways:
- Changing the number or order of the parameter OR
- Using different data types
Example:
using System;
class Overloading {
// adding two integer values.
public int Sum(int a, int b)
{
int total = a + b;
return total;
}
// adding three integer values.
public int Sum(int a, int b, int c)
{
int total = a + b + c;
return total;
}
// Main Method
public static void Main(String[] args)
{
// Creating Object
Overloading ol = new Overloading ();
int total1 = ol.Sum(1, 2);
Console.WriteLine(total1);
int total2 = ol.Sum(1, 2, 3);
Console.WriteLine(sum2);
}
}
Note: Important C# interview questionCompiler Time Constants:
These constants are compiled during compile time itself i.e, these are replaced by their values as soon as it is compiled.
Compiler-time constants are faster than run-time constants, and if performance is of importance to you these constants are preferred.
Run Time Constants:
The value of these constants is only known or computed when the source code is run. But once they are computed the values in these constants cannot be changed.
Because of this, they are more flexible than compile-time constants but this makes them slower.
Note: Commonly asked C# interview question- Singleton classes can be initialized. Static classes cannot be initialized.
- Singleton classes can be extended whereas static classes cannot be extended.
- When the program containing the class is loaded the compiler automatically loads the static classes, this is not true for singleton classes.
Serialization is the process that enables C# objects to be converted into a stream of bytes allowing them to be stored or sent across networks and applications. The receiving application uses deserialization to extract the data for further use.
Due to this, it is used widely in web services for transferring data between servers and clients.
The major disadvantage of serialization can be attributed to the resources used and data latency is a common issue faced. Furthermore, serialization is quite slow and XML, a type of serialization, isn't considered to be very secure.
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace DemoSerialization
{
[Serializable]
public class Employee
{
public int empCode;
public string empName;
[XmlAttribute(empName)]
public string EmpName
{
get
{
return empName;
}
set
{
empName = value;
}
}
}
}
Note: Important C# interview questionA delegate is a type that refers to and holds the reference of a particular method. These methods are associated when a delegate is instantiated.
Delegates are similar to function pointers in C++, however, they are fully object-oriented, unlike C++.
They are type-safe pointers and are mainly used to pass methods as arguments to other methods and events handles.
The syntax of delegates is as follows:
[delegate_name] [instance_name] = new [delegate_name](calling_method_name);
Note: Important C# interview questionSealed Classes:
Sealed classes restrict users from using inheritance, preventing the user from inheriting another class from it.
Sealed classes are defined using the sealed keyword. Given the inheritance attribute has been taken away, sealed classes work best when used with a class containing static members.
Syntax of Sealed class:
sealed class class_name
{
// data members
// methods
.
}
Partial Classes:
A partial class allows users to split the functionality of a class across the same file or even multiple files. During compilation, all instances are combined and treated as one.
Partial classes are defined using the partial keyword. Splitting a class allows multiple developers to work with the same class simultaneously. However, keep in mind that if any instance of the class is declared - sealed, abstract, or base - the whole class is declared with the same type.
Syntax of Partial class:
public partial Clas_name
{
// code
}
Note: Commonly asked C# interview questionC# throws a compilation error whenever variables are assigned as null.
The nullable type was a feature that was later introduced to allow users to assign null values to variables.
Nullable types are majorly used in database applications where tables need to be set to null or while representing undefined values.
The syntax to declare a nullable type is as follows:
Datatype? variable_name=null;
- Once defined, a single generic type can be used in the same code for multiple purposes - increasing reusability and reducing code redundancy.
- Generics provide significantly better performance in comparison to normal system types by reducing the need for type conversion and typecasting of variables to objects.
- Lastly, generics provide better type safety. Objects that are allowed to pass to a collection need to be defined while using a generic. This ensures that only an object of a particular type is passed.
The extension method in C# allows users to add new methods to an existing one. The main advantage of using an extension method is that it adds new methods without using inheritance and does not modify the source code of the existing class.
The code to do the same is as follows:
using System;
namespace Extension {
class NewClass {
// Method 1
public void Method_1()
{
Console.WriteLine("Method 1");
}
}
}
namespace Extension {
static class NewExtention {
// Method 2
public static void Method_2(this NewClass f)
{
Console.WriteLine("Method 2");
}
}
}
public class AllMethods {
// Main Method
public static void Main(string[] args)
{
NewClass f = new NewClass();
f.Method_1();
f.Method_2();
}
}
}
Note: Commonly asked C# interview questionEarly Binding:
Early binding is when an object is assigned to an object variable during compile time. The performance of early binding is much faster as the compiler already knows the methods and properties the object holds. This also decreases the number of run-time errors.
// C# program to show Early Binding
using System;
class EarlyBinding {
public string name;
public string language;
// public method
public void details(string name, string language)
{
this.name = name;
this.language = language;
Console.WriteLine(name);
Console.WriteLine(language);
}
}
class DriverClass {
// Main Method
static void Main(string[] args)
{
EarlyBinding e = new EarlyBinding ();
e.details("Eric", "English");
e.mymethod();
}
}
Late Binding:
Contrary to early binding, late binding is when the compiler does not know the properties an objects hold. The type of the object is decided during run-time based on the data it holds. The performance of late binding is slower as it requires lookups during run-time.
// C# program to show Late Binding
using System;
class LateBinding {
static void Main()
{
// Dynamic objects
dynamic obj = 7;
dynamic obj1 = 7.543;
// Display the type of objects
Console.WriteLine("Type of the objects:");
Console.WriteLine(obj.GetType());
Console.WriteLine(obj1.GetType());
}
}
Note: Important C# interview questionBoxing:
The type conversion process of converting a value type to a reference type is called boxing. i.e (int, char, etc) to (object).
Boxing is an implicit conversion process and the reference type is stored in heap.
int num = 23;
Object Obj = num;
Unboxing:
The process of doing the inverse i.e. converting a reference type into a value type is called unboxing.
Unboxing is an explicit conversion process and the value type is stored in a stack.
int num = 23;
Object Obj = num;
int i = (int)Obj;
Note: Commonly asked C# interview questionValue type variables are int, char, etc and they are usually performant. They are preferred over reference types for their higher functionality and accuracy.
Reference type variables are used when memory management is a vital factor and while dealing with larger values.
The IDisposable interface is used for the dispose() methods. This method is declared using the IDisposable interface to clean disposable objects and release unmanaged resources that the object contains. These resources could be files, streams, database connections etc.
using System;
using System.ComponentModel;
public class IDisposeExample
{
public class Resources: IDisposable
{
private IntPtr handle;
private Component component = new Component();
private bool disposed = false;
public Resources(IntPtr handle)
{
this.handle = handle;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
component.Dispose();
CloseHandle(handle);
handle = IntPtr.Zero;
disposed = true;
}
}
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
~Resources()
{
Dispose(false);
}
}
public static void Main()
{
// Insert code here to create
// and use the MyResource object.
}
}
Note: Commonly asked C# interview questionA thread is a lightweight program that defines a unique flow of control for a program. A thread cycle starts when an object of system.threading class is created and the thread is given a state based on the execution flow of the program.
The execution time of each thread can be managed individually. This ensures that two different threads do not overlap each other. Furthermore, resources are used efficiently and it prevents deadlocks.
Following are stated in a thread's lifecycle:
- Aborted – The thread is dead but not stopped
- Running – The thread is executing
- Stopped – The thread has stopped execution
- Suspended – The thread has been suspended
- Unstarted – The thread is created but has not started execution yet
- WaitSleepJoin – The thread calls sleep, calls wait on another object, and calls join on some other thread
static void Main(strong[] args)
{
string[] languages = {“C#”, “Python”, “Java”};
foreach(string s in languages)
{
if(System.Text.RegularExpressions.Regex.IsMatch(s,“C#”))
{
Console.WriteLine(“Match found”);
}
}
}
Note: Commonly asked C# interview questionThe process of accessing the metadata of the methods, types, and fields in a code during runtime is called reflection.
The System.Reflection method enables you to obtain this data.
// C# program to illustrate
// the use of Reflection
using System;
using System.Reflection;
namespace ReflectionExample {
class Reflection {
// Main Method
static void Main(string[] args)
{
// Initialise t as typeof string
Type t = typeof(string);
// Use Reflection to find about
// any sort of data related to t
Console.WriteLine("First Name : {0}", t.FirstName);
Console.WriteLine("Last Name : {0}", t.LastName);
}
}
}
Note: Important C# interview questionIn the singleton design pattern, a class is allowed only a single instance of itself and provides a global point of access to it.
There are multiple ways to implement a singleton pattern:
Singleton that isn't thread-safe
public sealed class Singleton1 {
private Singleton1() {}
private static Singleton1 n = null;
public static Singleton1 n {
get {
if (n == null) {
n = new Singleton1();
}
return n;
}
}
}
Thread-safe Singleton
public sealed class Singleton2 {
Singleton2() {}
private static readonly object lock = new object();
private static Singleton2 n = null;
public static Singleton2 n{
get {
lock(lock) {
if (n == null) {
n = new Singleton2();
}
return n;
}
}
}
}
Thread safe Singleton using double-check locking
public sealed class Singleton3 {
Singleton3() {}
private static readonly object lock = new object();
private static Singleton3 n = null;
public static Singleton3 n {
get {
if (n == null) {
lock(lock) {
if (n == null) {
n = new Singleton3();
}
}
}
return n;
}
}
}
Note: Commonly asked C# interview question- Binary Serialization – In this method, the objects are converted into binary form. Hence, this is the fastest method and takes up the least space for storage.
- SOAP – In this method of serialization, the objects are converted into a SOAP-compliant envelope. These envelopes can be used by any system that understands SOAP. SOAP classes are stored in the System.Runtime.Serialization.
- XML Serialization – All the public properties are converted into an XML document. This method of serialization is easily readable and can be manipulated into several other formats. XML serialized classes are stored in the System.sml.Serialzation.
using System;
using System.Collections;
class ParentClass {
// Providing the implementatio
public void ParentMethod()
{
// Creating ArrayList
ArrayList My_skills= new ArrayList();
// Adding elements in the
// My_features ArrayList
My_skills.Add("C#");
My_skills.Add("Java");
Console.WriteLine("My skills are");
foreach(var skills in My_skills)
{
Console.WriteLine(skills);
}
}
}
// Parent class 2
class ParentClass2 : ParentClass {
// Providing the implementation
// of courses() method
public void projects()
{
// Creating ArrayList
ArrayList My_projects = new ArrayList();
// Adding elements in the
// My_features ArrayList
My_projects.Add("Reminder Bot");
My_projects.Add("To-Do App");
Console.WriteLine("\nProject completed:");
foreach(var project in My_projects)
{
Console.WriteLine(project);
}
}
}
// Child class
class ChildClass : ParentClass2 {
}
public class profile {
// Main method
static public void Main()
{
// Creating object of Childclass class
Childclass obj = new Childclass ();
obj.skills();
obj.project();
}
}
Note: Important C# interview question