Showing 50 question(s)
Answer:
Value types store their actual data and are typically allocated on the stack. Examples include int, bool, double, and struct. Reference types store a reference to the object, which is allocated on the heap. Examples include class, string, array, and delegate. Assigning a value type creates a copy, whereas assigning a reference type copies only the reference.
Code Example:
// Value Type
int a = 10;
int b = a;
b = 20;
Console.WriteLine(a); // 10
Console.WriteLine(b); // 20
// Reference Type
class Person
{
public string Name { get; set; }
}
Person p1 = new Person { Name = "John" };
Person p2 = p1;
p2.Name = "David";
Console.WriteLine(p1.Name); // DavidAnswer:
Nullable types allow value types to hold null values. They are declared using the ? operator. Nullable types are useful when a value is optional, such as database fields that may contain NULL.
Code Example:
int? age = null;
if (age.HasValue)
{
Console.WriteLine(age.Value);
}
else
{
Console.WriteLine("Age not available");
}
Console.WriteLine(age ?? 18);Answer:
Boxing converts a value type into an object. Unboxing converts the object back to its original value type. Boxing creates a new object on the heap, so excessive boxing should be avoided.
Code Example:
int number = 100;
// Boxing
object obj = number;
// Unboxing
int value = (int)obj;
Console.WriteLine(value);Answer:
The var keyword determines the type at compile time, while dynamic resolves the type at runtime. The compiler performs type checking for var but skips compile-time checking for dynamic.
Code Example:
var name = "Learner Cabin";
// name = 10; // Compile-time error
dynamic data = "Hello";
data = 100;
data = true;
Console.WriteLine(data);Answer:
A const variable must be initialized at compile time and cannot change. A readonly field can be assigned either during declaration or inside the constructor and remains constant afterward.
Code Example:
class Demo
{
public const double PI = 3.14159;
public readonly DateTime CreatedDate;
public Demo()
{
CreatedDate = DateTime.Now;
}
}Answer:
A class is a reference type and supports inheritance. A struct is a value type, is copied by value, and cannot inherit from another struct or class. Structs are generally used for lightweight objects.
Code Example:
struct Point
{
public int X;
public int Y;
}
class Employee
{
public string Name { get; set; }
}Answer:
An abstract class can contain implemented methods, constructors, and fields. An interface defines a contract that implementing classes must follow. A class can inherit only one abstract class but implement multiple interfaces.
Code Example:
abstract class Animal
{
public abstract void Speak();
public void Sleep()
{
Console.WriteLine("Sleeping");
}
}
interface IFly
{
void Fly();
}Answer:
Method overloading allows multiple methods with the same name but different parameters in the same class. Method overriding allows a derived class to provide its own implementation of a virtual method.
Code Example:
class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public double Add(double a, double b)
{
return a + b;
}
}
class Animal
{
public virtual void Speak()
{
Console.WriteLine("Animal");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Bark");
}
}Answer:
virtual allows a method to be overridden. override provides a new implementation in a derived class. sealed prevents further overriding of an overridden method.
Code Example:
class Animal
{
public virtual void Speak()
{
Console.WriteLine("Animal");
}
}
class Dog : Animal
{
public sealed override void Speak()
{
Console.WriteLine("Dog");
}
}Answer:
Access modifiers control the visibility of classes and members. Common modifiers include public, private, protected, internal, protected internal, and private protected.
Code Example:
public class Employee
{
public string Name;
private int salary;
protected void CalculateSalary()
{
}
internal void Save()
{
}
}Answer:
A delegate is a type-safe function pointer that references one or more methods with the same signature. Delegates are commonly used for callbacks and event handling.
Code Example:
public delegate void Greeting(string name);
class Program
{
static void SayHello(string name)
{
Console.WriteLine($"Hello {name}");
}
static void Main()
{
Greeting greet = SayHello;
greet("Learner Cabin");
}
}Answer:
Events allow a class to notify subscribers when something happens. They are based on delegates and follow the publisher-subscriber pattern.
Code Example:
public class Alarm
{
public event Action Ring;
public void Trigger()
{
Ring?.Invoke();
}
}
Alarm alarm = new Alarm();
alarm.Ring += () => Console.WriteLine("Alarm Triggered!");
alarm.Trigger();Answer:
Exception handling uses try, catch, finally, and throw keywords to detect and handle runtime errors gracefully.
Code Example:
try
{
int result = 10 / 0;
}
catch (DivideByZeroException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("Execution Completed");
}Answer:
Arrays have a fixed size, whereas List<T> is dynamically resizable and provides many built-in methods like Add, Remove, Find, and Sort.
Code Example:
int[] numbers = {1,2,3};
List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
foreach(var item in list)
{
Console.WriteLine(item);
}Answer:
Generics allow classes, interfaces, and methods to work with different data types while maintaining type safety and avoiding code duplication.
Code Example:
class Box<T>
{
public T Value { get; set; }
}
Box<int> number = new Box<int>();
number.Value = 100;
Console.WriteLine(number.Value);Answer:
LINQ (Language Integrated Query) provides a consistent syntax to query collections, XML, databases, and other data sources directly in C#.
Code Example:
List<int> numbers = new() {1,2,3,4,5,6};
var even = numbers.Where(n => n % 2 == 0);
foreach(var item in even)
{
Console.WriteLine(item);
}Answer:
Extension methods allow developers to add new methods to existing classes without modifying their source code or creating derived classes.
Code Example:
public static class StringExtensions
{
public static string ReverseText(this string text)
{
return new string(text.Reverse().ToArray());
}
}
Console.WriteLine("Hello".ReverseText());Answer:
The async and await keywords simplify asynchronous programming by allowing long-running operations to execute without blocking the calling thread.
Code Example:
public async Task DownloadAsync()
{
await Task.Delay(2000);
Console.WriteLine("Download Complete");
}
await DownloadAsync();Answer:
Garbage Collection automatically frees memory occupied by objects that are no longer referenced, reducing memory leaks and simplifying memory management.
Code Example:
class Person
{
public string Name { get; set; }
}
Person p = new Person();
p = null;
// Suggest garbage collection
GC.Collect();
Console.WriteLine("Garbage Collection Requested");Answer:
Dependency Injection is a design pattern where dependencies are provided from outside a class rather than created inside it. It improves testability, maintainability, and loose coupling.
Code Example:
public interface IMessageService
{
void Send();
}
public class EmailService : IMessageService
{
public void Send()
{
Console.WriteLine("Email Sent");
}
}
public class Notification
{
private readonly IMessageService _service;
public Notification(IMessageService service)
{
_service = service;
}
public void Notify()
{
_service.Send();
}
}
var notification = new Notification(new EmailService());
notification.Notify();Answer:
List<T> stores items sequentially and is accessed by index, whereas Dictionary<TKey, TValue> stores key-value pairs and provides faster lookups using keys.
Code Example:
List<string> fruits = new()
{
"Apple",
"Orange"
};
Dictionary<int, string> employees = new()
{
{1, "John"},
{2, "David"}
};
Console.WriteLine(fruits[0]);
Console.WriteLine(employees[2]);Answer:
String objects are immutable, meaning every modification creates a new object. StringBuilder is mutable and is recommended when performing multiple string modifications.
Code Example:
using System.Text;
StringBuilder sb = new StringBuilder();
sb.Append("Hello ");
sb.Append("World");
Console.WriteLine(sb.ToString());Answer:
IDisposable provides a mechanism to release unmanaged resources such as database connections, file handles, and network streams.
Code Example:
using(FileStream file =
new FileStream("test.txt", FileMode.OpenOrCreate))
{
// Work with file
}
// Dispose() called automaticallyAnswer:
The using statement automatically disposes objects implementing IDisposable after they are no longer needed.
Code Example:
using(StreamReader reader =
new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}Answer:
Lambda expressions provide a concise syntax for writing anonymous functions and are widely used with LINQ.
Code Example:
List<int> numbers = new()
{
1,2,3,4,5
};
var even = numbers.Where(x => x % 2 == 0);
foreach(var n in even)
{
Console.WriteLine(n);
}Answer:
Action represents a method with no return value. Func represents a method with a return value. Predicate returns a boolean value and is commonly used for filtering.
Code Example:
Action<string> greet =
name => Console.WriteLine($"Hello {name}");
Func<int, int, int> add =
(a, b) => a + b;
Predicate<int> isEven =
x => x % 2 == 0;
greet("John");
Console.WriteLine(add(5,3));
Console.WriteLine(isEven(10));Answer:
Deferred execution means a LINQ query is executed only when its results are actually enumerated.
Code Example:
List<int> numbers = new()
{
1,2,3
};
var query = numbers.Where(x => x > 1);
numbers.Add(4);
foreach(var item in query)
{
Console.WriteLine(item);
}Answer:
A Task represents an asynchronous operation and is part of the Task Parallel Library (TPL).
Code Example:
Task task = Task.Run(() =>
{
Console.WriteLine("Running...");
});
await task;Answer:
Thread is a low-level construct managed by the operating system. Task is a higher-level abstraction managed by the Task Parallel Library and is generally preferred.
Code Example:
Thread thread = new Thread(() =>
{
Console.WriteLine("Thread");
});
thread.Start();
Task.Run(() =>
{
Console.WriteLine("Task");
});Answer:
throw preserves the original stack trace, while throw ex resets the stack trace, making debugging more difficult.
Code Example:
try
{
throw new Exception("Error");
}
catch(Exception ex)
{
// Preferred
throw;
// Avoid
// throw ex;
}Answer:
Method hiding occurs when a derived class defines a method with the same name as a base class method using the new keyword. Unlike overriding, the base method is hidden instead of being replaced.
Code Example:
class Animal
{
public void Speak()
{
Console.WriteLine("Animal speaks");
}
}
class Dog : Animal
{
public new void Speak()
{
Console.WriteLine("Dog barks");
}
}Answer:
Auto-implemented properties allow you to define properties without explicitly declaring backing fields.
Code Example:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}Answer:
IEnumerable<T> represents a sequence of objects that can be iterated using foreach. It supports forward-only iteration.
Code Example:
IEnumerable<int> numbers = new List<int>
{
1,2,3,4
};
foreach(var number in numbers)
{
Console.WriteLine(number);
}Answer:
IEnumerable<T> performs filtering in memory, whereas IQueryable<T> translates queries into SQL or another query language and executes them on the data source.
Code Example:
IQueryable<Employee> employees =
dbContext.Employees;
var result = employees
.Where(e => e.Salary > 50000)
.ToList();Answer:
Generic constraints restrict the types that can be used as generic arguments using keywords such as class, struct, new(), or a base class/interface.
Code Example:
class Repository<T>
where T : class, new()
{
public T Create()
{
return new T();
}
}Answer:
Extension methods extend existing types without modifying their source code. They are declared in static classes using the this keyword.
Code Example:
public static class NumberExtensions
{
public static bool IsEven(this int value)
{
return value % 2 == 0;
}
}
Console.WriteLine(10.IsEven());Answer:
The stack stores value types and method calls, while the heap stores objects created from reference types. Stack memory is automatically managed, whereas heap memory is cleaned by the Garbage Collector.
Code Example:
int age = 30; // Stack
Person person = new Person(); // Heap
class Person
{
public string Name { get; set; }
}Answer:
A custom exception is created by inheriting from the Exception class and defining appropriate constructors.
Code Example:
public class InvalidAgeException : Exception
{
public InvalidAgeException(string message)
: base(message)
{
}
}
throw new InvalidAgeException("Age must be 18 or older.");Answer:
First() throws an exception if no matching element exists, whereas FirstOrDefault() returns the default value (null for reference types).
Code Example:
List<int> numbers = new()
{
10,20,30
};
var first = numbers.First();
var result = numbers
.FirstOrDefault(x => x > 100);
Console.WriteLine(result); // 0Answer:
ConfigureAwait(false) tells the await operation not to capture the current synchronization context, improving performance in library and backend code.
Code Example:
public async Task LoadDataAsync()
{
await Task.Delay(1000)
.ConfigureAwait(false);
Console.WriteLine("Completed");
}Answer:
SOLID is a set of five object-oriented design principles: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion. They help create maintainable, scalable, and loosely coupled applications.
Code Example:
public interface ILogger
{
void Log(string message);
}
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}Answer:
Reflection allows inspecting metadata, types, properties, methods, and assemblies at runtime. It is commonly used in dependency injection frameworks, testing frameworks, and serializers.
Code Example:
Type type = typeof(string);
Console.WriteLine(type.Name);
foreach(var method in type.GetMethods())
{
Console.WriteLine(method.Name);
}Answer:
Attributes provide metadata about classes, methods, properties, or assemblies. They are commonly used for validation, serialization, dependency injection, and unit testing.
Code Example:
[Obsolete("Use NewMethod instead.")]
public void OldMethod()
{
}
public void NewMethod()
{
}Answer:
Dependency Injection is built into ASP.NET Core. Services are registered in the dependency injection container and automatically injected into constructors.
Code Example:
builder.Services.AddScoped<IProductService, ProductService>();
public class HomeController
{
private readonly IProductService _service;
public HomeController(IProductService service)
{
_service = service;
}
}Answer:
Records are immutable reference types introduced in C# 9. They are primarily used for storing data and provide built-in value equality.
Code Example:
public record Employee(int Id, string Name);
Employee emp = new(1, "John");
Console.WriteLine(emp.Name);Answer:
Pattern matching simplifies checking object types and extracting values using expressions such as is, switch, and relational patterns.
Code Example:
object value = 100;
if(value is int number)
{
Console.WriteLine(number);
}Answer:
Span<T> is a lightweight type that represents a contiguous region of memory. It improves performance by reducing allocations and copying.
Code Example:
int[] numbers = {1,2,3,4};
Span<int> span = numbers;
span[0] = 100;
Console.WriteLine(numbers[0]);Answer:
The yield keyword simplifies creating iterators by returning elements one at a time without creating a complete collection in memory.
Code Example:
public IEnumerable<int> GetNumbers()
{
yield return 1;
yield return 2;
yield return 3;
}
foreach(var number in GetNumbers())
{
Console.WriteLine(number);
}Answer:
Nullable reference types help developers identify potential NullReferenceException issues during compilation by distinguishing nullable and non-nullable references.
Code Example:
#nullable enable
string name = "John";
string? middleName = null;
Console.WriteLine(name);
Console.WriteLine(middleName);Answer:
Use meaningful naming conventions, follow SOLID principles, prefer dependency injection, avoid unnecessary object creation, use async/await appropriately, dispose unmanaged resources with using, handle exceptions properly, and write unit tests.
Code Example:
public async Task<string> GetDataAsync()
{
using HttpClient client = new();
return await client.GetStringAsync(
"https://example.com/api");
}