20 C# Advanced Interview Questions & Answers
Below is a list of our C# Advanced interview questions. Click on any interview question to view our answer advice and answer examples. You may view six answer examples before our paywall loads. Afterwards, you'll be asked to upgrade to view the rest of our answers.
1. What is a Generic class and how is it implemented?
This question shows the developer's ability to work with C# classes.
A generic class is a class in which the internal operations are not specific to a particular data type. This is commonly seen in the collections classes (Lists, HashTables, Stacks, etc) in .NET. A use case for creating your own generic class is where you wish to implement a reusable set of methods that are not type-specific by providing type parameters. The more parameters you provide, the more flexible and re-usable your code becomes. Software shops that provide APIs for clients, strive to implement reusability and flexibility.
// Declare the generic class.
public class GenericList<T>
{
// create a generic list to iterate through the added objects
System.Collections.Generic.List<T> list = new System.Collections.Generic.List<T>();
public System.Collections.Generic.List<T> MyList
{
get
{
return list;
}
}
public void Add(T input) {
list.Add(input);
}
}
class Program
{
public static void Main()
{
// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();
list1.Add(1);
list1.Add(2);
// Declare a list of type string.
GenericList<string> list2 = new GenericList<string>();
list2.Add("First string");
list2.Add("Second string");
//Grab the list from list1
System.Collections.Generic.List<int> lst1 = list1.MyList;
//Grab the list from list2
System.Collections.Generic.List<string> lst2 = list2.MyList;
// iterate through the int members in list1
foreach (int item in lst1)
{
Console.WriteLine(item);
}
// interate through the string members in list2
foreach (string item in lst2)
{
Console.WriteLine(item);
}
}
}
Written by Edward Danganan on April 21st, 2021
2. C# 9.0 - Provide an example of using a 'with' expression
This interview question shows the developer's understanding of C# expressions.
The 'with' expression allows you to copy a record type to another instance, keeping the unchanged values the same, but allowing you to create a new instance and changing only the values you wish to change. This offers convenience in not having to redefine the variable values
Animal animal1 = new("Feline", "Aspthicus");
var animal2 = animal1 with {Specie = "Baculatus" };
Console.WriteLine(animal1.Genus +" "+ animal1.Specie);// output Feline Aspthicus
Console.WriteLine(animal2.Genus+" "+animal2.Specie); // output Feline Baculatus
Written by Edward Danganan on April 21st, 2021
3. C# 9.0 - What is an init-only setter?
This interview question shows the developer's understanding of C# features.
This construct provides a clear, concise way of initializing a property. Properties defined in this way are read-only once defined. Attempting to change the property will result in a compiler error.
// Define a struct with the init setter
public struct Product
{
public decimal Price { get; init; }
public string ProductName{ get; init; }
public string SKU { get; init; }
}
// compiles fine
var shampoo = new Product
{
Price = 4.99M,
ProductName = "My Excellent Shampoo",
SKU = "FFH2209"
};
// Trying to change any of the properties after construction will result in an error as shown below
//Severity Code Description Project File Line Suppression State
//Error CS8852 Init - only property or indexer 'Program.Product.SKU' can only be assigned in an object
//initializer, or on 'this' or 'base' in an instance constructor or an
//'init' accessor.Active
shampoo.SKU = "FFLXI220";
Written by Edward Danganan on April 21st, 2021
4. C# 9.0 - What is a record type?
This interview question shows the developer's understanding of C# reference types and features.
The latest version of C#, version 9, came out in September of 2020. Keeping up with the latest version of a language and noting its key features is an expectation of an experienced developer. You should be prepared to name a few of these features. The next few questions pertain to 9.0 features.
A record type was introduced in 9.0 and is a way of quickly creating a reference type instead of a class or struct. It is denoted by the 'record' keyword. Records use value-based equality, which means that two variables in a record type are equal if their definitions are identical and if the values of every field in the compared record tyes are equal.
// this is an example of creating a new record type
public record Animal(string Genus, string Specie);
Animal animal1 = new("Feline", "Aspthicus");
Animal animal2 = new("Feline", "Aspthicus");
Console.WriteLine(animal1 == animal2); // output: True
Console.WriteLine(animal1 == animal2); // output: True
Console.WriteLine(ReferenceEquals(animal1, animal2)); // output: False; they are different objects
Written by Edward Danganan on April 21st, 2021
5. How would you access a file directory and iterate through the contents of a particular directory?
This question concentrates on the developer's ability to use C# methods.
A fundamental requirement of many applications, particularly desktop apps, is the ability to retrieve information from the file system. This is often to store, update or retrieve configuration data, persist application state, or store user-specific data. It is therefore important to know how this would be accomplished through code. The example below shows code for going through a directory, in this case, the root directory.
using System;
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
// Start with drives if you have to search the entire computer.
string[] drives = System.Environment.GetLogicalDrives();
foreach (string dr in drives)
{
System.IO.DriveInfo di = new System.IO.DriveInfo(dr);
// Here we skip the drive if it is not ready to be read. This
// is not necessarily the appropriate action in all scenarios.
if (!di.IsReady)
{
Console.WriteLine("The drive {0} could not be read", di.Name);
continue;
}
System.IO.DirectoryInfo rootDir = di.RootDirectory;
WalkDirectoryTree(rootDir);
}
}
/// <summary>
/// Holder object for the file names
/// </summary>
static System.Collections.Specialized.StringCollection log = new System.Collections.Specialized.StringCollection();
static void WalkDirectoryTree(System.IO.DirectoryInfo root)
{
System.IO.FileInfo[] files = null;
// First, process all the files directly under this folder, which in this case is the root directory
try
{
files = root.GetFiles("*.*");
}
// This is thrown if even one of the files requires permissions greater
// than the application provides.
catch (UnauthorizedAccessException e)
{
// This code just writes out the message and continues to recurse.
// You may decide to do something different here. For example, you
// can try to elevate your privileges and access the file again.
log.Add(e.Message);
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
}
if (files != null)
{
foreach (System.IO.FileInfo fi in files)
{
// Go through the files' names and perform logic on the file once you have found
// the file you want to interrogate. For the purpose of this example, just write out the names of the files
Console.WriteLine(fi.FullName);
}
}
}// end method
}
}
Written by Edward Danganan on April 21st, 2021
6. Provide code that shows how you would iterate over a result set from a database query.
This interview question shows developer knowledge of C# methods.
Once you have instantiated a connection object and opened it, you'll need to retrieve the result set and perform some action on it or return it to another method for further
processing.
using (System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connStr)){
con.Open();
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("select column1, column2, column3 from someTable");
System.Data.SqlClient.SqlDataReader rdr = cmd.ExecuteReader();
string col1value = string.Empty;
string col2value = string.Empty;
string col3value = string.Empty;
while (rdr.Read())
{
// retrieve your values, perform some logic on them or rehydrate an object with the returned values
col1value = rdr["column1"].ToString();
col2value = rdr["column2"].ToString();
col3value = rdr["column3"].ToString();
}
}
Written by Edward Danganan on April 21st, 2021
7. When you connect to a database in your code, what are methods you would use to clean up resources no longer needed.
This question concentrates on the C# database connection.
When connecting to a database, it is very important that resources no longer needed are cleaned up. Not doing so could deteriorate application performance
It is, therefore, a best practice to close your connection object when your result set is returned or you are finished with the database updates
try
{
con.Open();
// add code here to iterate through your result set
}
catch (Exception e){
// log the error
// handle it here or throw it up the stack for the application to handle
throw e;
}
finally
{
//Regardless of what happens in the try/catch blocks, the final block will always be executed.
//You should add your clean-up code here, which in this case, is closing your connection object con.Close();
}
// You can also wrap the connection objection creation in a using block. All resources in the block will be cleaned up as well.
using (System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connStr)){
con.Open();
}
Written by Edward Danganan on April 21st, 2021
8. You have an application that requires connectivity to SQL Server. Provide code that shows how to accomplish this.
This interview question focuses on database connection using C#.
Many applications will require some type of database connectivity to return a recordset, update data, persist user data, etc. It is expected that a developer knows the basics of how to set up, instantiate, and use a connection object to perform the necessary insert, update, return, and delete actions on a database.
/**This code shows how you would retrieve the connection string from the ConnectionString section of a web.config file for a web application. **/
string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["nameOfConfigurationSectionInWebConfig"].ConnectionString;
/** For the purposes of this example, the assumption is a connection to a Sql Server database is required
There are third party data provider assemblies which will allow you to connect to other datastores (ie. MySql, Oracle MS Access) **/
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connStr);
Written by Edward Danganan on April 21st, 2021
9. Provide an example of a tuple?
This interview question concentrates on the developer's knowledge of C# syntax.
Available since C# 7.0, the tuple feature is a data structure that allows you to store multiple data types. An interviewer may ask you about the various ways to hold multiple data types, other than a Generic class.
(double, int, string) t1 = (9.5, 6, "Hello");
Console.WriteLine($"Tuple with elements {t1.Item1}, {t1.Item2} and {t1.Item3}.");
// Output:
// Tuple with elements 9.5, 6, 'Hello'.
Written by Edward Danganan on April 21st, 2021
10. What is a Nullable value type?
This interview question shows understanding of C# data types.
A nullable value type allows you to define a variable that is capable of handling a null value type. This is indicated by the '?' symbol after the data type definition. Prior to this feature, assigning a variable to a null value type would result in an exception. A technical interviewer would expect an experienced developer to know about this feature as there will be times when your application will be expected to deal with null types.
int? a = null ;
if (a is int somevalue)
{
Console.WriteLine($"a is {somevalue}");
}
else
{
Console.WriteLine("a does not have a value");
}
// Output:
// a does not have a value
int? a = 23;
if (a is int somevalue)
{
Console.WriteLine($"a is {somevalue}");
}
else
{
Console.WriteLine("a does not have a value");
}
// Output:
// a is 23
Written by Edward Danganan on April 21st, 2021
11. Describe the difference between boxing and unboxing.
This interview question focuses on C# terminology.
Boxing is the process for converting a value type to a reference type and conversion of that same reference type //back to its value type is unboxing. This is a fundamental concept that advanced object-oriented programmers //should be expected to know.
//Boxing
object boxedValue = Value1;
//Unboxing
string unboxedValue = boxedValue.ToString();
Written by Edward Danganan on April 21st, 2021
12. How are Events implemented in C#?
This question shows the developer's ability to work with C# events.
Events allow classes or other objects to notify other classes or objects about actions they may be interested in. The originating objects (publishers) contain event objects which interested objects (subscribers) can be notified about. This paradigm is pervasive within Windows forms and web applications and is, therefore, an important concept to know about.
using System;
namespace MyNamespace
{
// Define a class to hold custom event info
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
}
// Class that publishes an event
class Publisher
{
// Declare the event using EventHandler<T>
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
public string notifyingMessage = string.Empty;
public void DoSomething()
{
// Write some code that does something useful here
// then raise the event. You can also raise an event
// before you execute a block of code.
notifyingMessage = "Performing some type of task";
OnRaiseCustomEvent(new CustomEventArgs("Event triggered"));
}
// Wrap event invocations inside a protected virtual method
// to allow derived classes to override the event invocation behavior
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent;
// Event will be null if there are no subscribers
if (raiseEvent != null)
{
// Format the string to send inside the CustomEventArgs parameter
e.Message += $" at {DateTime.Now}";
// Call to raise the event.
raiseEvent(this, e);
}
}
}
//Class that subscribes to an event
class Subscriber
{
private readonly string _id;
protected Publisher p;
public Subscriber(string id, Publisher pub)
{
_id = id;
p = pub;
// Subscribe to the event
pub.RaiseCustomEvent += HandleCustomEvent;
}
// Define what actions to take when the event is raised.
void HandleCustomEvent(object sender, CustomEventArgs e)
{
Console.WriteLine($"{_id} received this message: {e.Message}");
Console.WriteLine(p.notifyingMessage);
}
}
class Program
{
public static void Main()
{
var pub = new Publisher();
var sub1 = new Subscriber("sub1", pub);
var sub2 = new Subscriber("sub2", pub);
// Call the method that raises the event.
pub.DoSomething();
}
}
}
Written by Edward Danganan on April 21st, 2021
13. What is the difference between async and sync processes?
This interview question tests the developer's knowledge of C# operations.
A synchronous process limits access to a resource for one thread at a time. If two or more threads are trying to access the same resource at the same time, one of those threads may block the others. In asynchronous calls, two or more threads can access a resource independent of the other processes. By default, an application is a single-threaded or synchronous program. It is important for the programmer to know when to utilize asynchronous versus synchronous method calls. Running asynchronous threads may provide your application the opportunity to work on other tasks while the main program executes, resulting in a better user experience. Writing asynchronous code is more effort and can be difficult to debug, so you'll need to determine which approach to use based upon the application requirements.
Written by Ryan Brown on May 17th, 2021
14. What are the different Thread states?
This question focuses on the developer's knowledge of C# terminology and thread levels.
Unstarted - The thread is created.
Running - The thread starts execution.
WaitSleepJoin - The thread calls sleep, calls wait on another object and calls join on another thread.
Suspended - The thread has been suspended.
Aborted - The thread is dead but the state has not changed to stop.
Stopped - The thread has stopped.
Based upon the state of the given thread, you can incorporate logic to control the action of a given thread.
Written by Ryan Brown on May 17th, 2021
15. What is Threading?
This interview question shows the developer's knowledge of C# terminology.
Threading enables an application to perform a set of instructions concurrently, allowing a program to execute more than one operation at a time. When you create the Main program, this invokes only one thread. You can create multiple threads which can perform other operations at the same time. A multithreaded application gives the application an opportunity to maximize the use of the computer's CPU time.
Written by Ryan Brown on May 17th, 2021
16. Once an object is persisted through serialization, show an example of how it can be de-serialized.
This question tests a developer's understanding of C# classes.
Once you've serialized the object, you're going to need to re-hydrate it when needed. This example assumes you are using the previously created Serialzing method.
namespace ConsoleApp1 {
class Program
{
static void Main(string[] args)
{
// call the method to serialize the object
SerialzingMethod();
}
static void SerialzingMethod()
{
ASerializableObject something = new ASerializableObject();
something.Name = "Serialization Exampe";
System.Xml.Serialization.XmlSerializer writer =
new System.Xml.Serialization.XmlSerializer(typeof(ASerializableObject));
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//SerializedObject.xml";
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, something);
file.Close();
}
}
static void DeserializingMethod()
{
//Call the previously created Serializing method
SerialzingMethod();
// Now we can read the serialized obj
System.Xml.Serialization.XmlSerializer reader =
new System.Xml.Serialization.XmlSerializer(typeof(ASerializableObject));
// Get the serialized object
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//SerializedObject.xml";
System.IO.StreamReader file = new System.IO.StreamReader(path);
ASerializableObject rehydratedObj = (ASerializableObject)reader.Deserialize(file);
file.Close();
// display the name of the serialized object
Console.WriteLine(rehydratedObj.Name);
}
public class ASerializableObject
{
public String Name;
}
}
Written by Edward Danganan on April 21st, 2021
17. What is serialization and how is it used?
This interview question shows the developer's understanding of C# terminology and objects conversion.
Serialization is the process of converting an object to a stream of bytes which can then be stored in memory, to a database, or to a file. It allows the application to store the state of an object at a point in time, for the purposes of re-hydrating it as necessary. Such uses can be passing object data from one domain to another or to a web service endpoint. In ASP.net, the ViewState object of a page is another example of serialization. ViewState provides a convenient way of persisting the page state and its objects between post-backs. As an experienced C# developer, you will need to know the various use cases for serialization, as object persistence is a necessary concept in OO programming.
In this example, a Serializable object is persisted in XML and saved as a file to the MyDocuments folder on the local system.
namespace ConsoleApp1 {
class Program
{
static void Main(string[] args)
{
// call the method to serialize the object
SerialzingMethod();
}
static void SerialzingMethod()
{
ASerializableObject something = new ASerializableObject();
something.Name = "Serialization Exampe";
System.Xml.Serialization.XmlSerializer writer =
new System.Xml.Serialization.XmlSerializer(typeof(ASerializableObject));
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//SerializedObject.xml";
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, something);
file.Close();
}
}
public class ASerializableObject
{
public String Name;
}
}
Written by Edward Danganan on April 21st, 2021
18. What is a 'race' condition?
This interview question shows the developer's understanding of C# terminology and thread synchronization.
A race condition arises when a multithreaded application accesses and manipulates a shared resource simultaneously. This may result in unexpected results and cause issues. This situation can be avoided by added a lock mechanism in thread code before action on the shared resource occurs. This situation is common in other coding scenarios so it is an important concept to be aware of by conducting in-depth code reviews and extensive testing when there is a chance it may occur in your application.
Written by Ryan Brown on May 17th, 2021
19. What is reflection?
This question shows that a developer is able to obtain data from code in C#.
Reflection enables code to discover the metadata of an assembly at runtime. The program can then use information about a class (ie, its methods, properties, and other members) in order to incorporate additional logic to the application, based upon what is discovered about a class. If you have a third-party assembly, you may not have been provided sufficient API documentation so you may need to rely upon reflection to discover more details about the class in order to perform further actions.
namespace ConsoleApp1 {
class Program
{
static void Main(string[] args)
{
MyClass cl = new MyClass();
// Get the Type of class
Type typeOfClass = cl.GetType();
// Obtain the membership information of the class
System.Reflection.MemberInfo []membersOfClass = typeOfClass.GetMethods();
foreach (System.Reflection.MemberInfo member in membersOfClass)
{
// get the method names of the class
Console.WriteLine(member.Name);
}
}
}
public class MyClass
{
public int FirstMethod() {
return 1;
}
public int SecondMethod()
{
return 2;
}
}
}
Written by Edward Danganan on April 21st, 2021
20. Explain the role of a delegate and provide an example.
This interview question shows the developer's ability to reference methods in C#
A delegate is a type-safe, method object similar to a method pointer in C or C++. It derives from the Delegate class and is sealed and therefore cannot be inherited. Since it is an object, it can be passed as a parameter to another method or assigned a property. Delegates are commonly used in C# event programming in response to user clicks to UI elements. A subscribing source object calls the delegate in response to an event. Delegates are a fundamental element in C# programming and are therefore important for a candidate to know how they are used.
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//Create an instance of the delegate and call it
MyDelegate delgte = MyCallback;
delgte()
}
// create a method for the delegate
static void MyCallback()
{
Console.WriteLine("Calling the delegate method");
}
//declare the delegate
delegate void MyDelegate();
}
}
Written by Edward Danganan on April 21st, 2021