Q6: What are access modifiers in C#?
Access modifiers in C# are keywords used to specify the accessibility of a class and its members. The main access modifiers are:
public class MyClass
{
private int privateField;
public int publicField;
protected int protectedField;
internal int internalField;
protected internal int protectedInternalField;
}
Q7: What is the difference between abstract classes and interfaces in C#?
Both abstract classes and interfaces can be used to define methods that must be implemented by derived classes. However, there are key differences:
// Abstract class
public abstract class Animal
{
public abstract void MakeSound();
public void Eat()
{
Console.WriteLine("Eating...");
}
}
// Interface
public interface IAnimal
{
void MakeSound();
}
// Implementing an abstract class
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Barking...");
}
}
// Implementing an interface
public class Cat : IAnimal
{
public void MakeSound()
{
Console.WriteLine("Meowing...");
}
}
Q8: What is polymorphism in C#?
Polymorphism is a core concept in object-oriented programming that allows methods to have different implementations based on the object they are acting upon. There are two types of polymorphism in C#:
virtual
and
override
keywords.
// Method Overloading
public class MathOperations
{
public int Add(int a, int b)
{
return a + b;
}
public double Add(double a, double b)
{
return a + b;
}
}
// Method Overriding
public class BaseClass
{
public virtual void Display()
{
Console.WriteLine("Base class display method");
}
}
public class DerivedClass : BaseClass
{
public override void Display()
{
Console.WriteLine("Derived class display method");
}
}
Q9: Explain the concept of delegates in C#.
A
delegate
in C# is a type that represents references to methods with a particular parameter list and return type. Delegates are used to pass methods as arguments to other methods. They are similar to function pointers in C++ but are type-safe and secure.
public delegate void DisplayMessage(string message);
public class MessageHandler
{
public void ShowMessage(string message)
{
Console.WriteLine(message);
}
}
public class Program
{
static void Main()
{
MessageHandler handler = new MessageHandler();
DisplayMessage del = new DisplayMessage(handler.ShowMessage);
del("Hello, World!");
}
}
Q10: What are events in C#?
Events in C# are a way for a class to notify other classes or objects when something of interest happens. Events are based on delegates. A class that raises an event is called a publisher , and a class that receives the event notification is called a subscriber .
public class Publisher
{
public delegate void Notify(); // Delegate
public event Notify OnNotify; // Event
public void DoSomething()
{
// Some code...
OnNotify?.Invoke();
}
}
public class Subscriber
{
public void Subscribe(Publisher publisher)
{
publisher.OnNotify += OnNotified;
}
private void OnNotified()
{
Console.WriteLine("Subscriber notified.");
}
}
class Program
{
static void Main()
{
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();
subscriber.Subscribe(publisher);
publisher.DoSomething(); // This will trigger the event
}
}
Request question
Please fill in the form below to submit your question.
Q11: What is the difference between String and string in C#?
In C#,
String
and
string
are essentially the same.
string
is an alias for
System.String
. They both represent a sequence of characters. The use of one over the other is a matter of style or convention. However,
string
is more commonly used in C# code, while
String
is used when referencing the .NET class directly.
Q12: What are properties in C# and how do they differ from fields?
Properties in C# are members that provide a flexible mechanism to read, write, or compute the values of private fields. Properties can have logic implemented in their get and set accessors, providing control over how values are accessed or modified. Fields, on the other hand, are simple variables that store data directly.
public class Person
{
private string name; // Field
public string Name // Property
{
get { return name; }
set { name = value; }
}
}
Q13: Explain the concept of method overloading.
Method overloading in C# is the ability to create multiple methods with the same name in the same class but with different parameters (different type, number, or both). It allows methods to handle different types of input in a flexible and readable way.
public class MathOperations
{
public int Add(int a, int b) => a + b;
public double Add(double a, double b) => a + b;
}
Q14: What is a struct in C# and how is it different from a class?
A
struct
in C# is a value type that can contain fields, methods, constructors, properties, and other members. Unlike classes, structs are value types and are typically used for small data structures that contain primarily data. Key differences:
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
Q15: What is the purpose of the using statement in C#?
The
using
statement in C# is used to ensure that
IDisposable
objects are properly disposed of once they are no longer needed. This is particularly important for managing unmanaged resources like file handles, database connections, or network connections. The
using
statement ensures that the
Dispose
method is called even if an exception occurs.
using (StreamReader reader = new StreamReader("file.txt"))
{
string content = reader.ReadToEnd();
}
Request question
Please fill in the form below to submit your question.
Q16: What is the difference between const and readonly in C#?
Both
const
and
readonly
are used to define fields whose values cannot be modified, but they have different use cases and behaviors:
const
is implicitly static.
public class Example
{
public const int ConstValue = 10; // Compile-time constant
public readonly int ReadOnlyValue; // Runtime constant
public Example(int value)
{
ReadOnlyValue = value; // Can only be set in the constructor
}
}
Q17: What are the different types of collections in C#?
C# provides several types of collections, categorized mainly into the following:
Q18: Explain the concept of exception handling in C#.
Exception handling in C# is a mechanism to handle runtime errors in a controlled and graceful manner using
try
,
catch
,
finally
, and
throw
keywords.
try:
Block of code where exceptions may occur.
catch:
Block of code that handles the exception.
finally:
Block of code that executes regardless of whether an exception is thrown or not.
throw:
Used to explicitly throw an exception.
try
{
int divisor = 0;
int result = 10 / divisor;
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Cannot divide by zero.");
}
finally
{
Console.WriteLine("Execution completed.");
}
Q19: What is LINQ in C#?
LINQ (Language Integrated Query) is a set of features in C# that provides query capabilities directly within the C# language. It allows querying various data sources, such as collections, SQL databases, XML documents, etc., using a consistent syntax. LINQ queries can be written using query syntax or method syntax.
int[] numbers = { 1, 2, 3, 4, 5 };
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
Q20: What is the difference between override and new keyword in C#?
Both
override
and
new
are used to redefine a method in a derived class, but they have different implications:
override:
Used to provide a new implementation of a virtual method defined in the base class. It requires the method in the base class to be marked as virtual, abstract, or override.
new:
Hides a method from the base class. It is used when the derived class wants to define a new implementation that is not related to the base class method.
public class BaseClass
{
public virtual void Display()
{
Console.WriteLine("Base class display method");
}
}
public class DerivedClass : BaseClass
{
public override void Display()
{
Console.WriteLine("Derived class display method");
}
}
public class AnotherDerivedClass : BaseClass
{
public new void Display()
{
Console.WriteLine("Another derived class display method");
}
}
Request question
Please fill in the form below to submit your question.
Request question
Please fill in the form below to submit your question.
(Basic)
public class Program
{
public static void Main(string[] args)
{
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
for (int i = 0; i <= numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
}
}
Expected Output: 1 2 3 4 5
There are two errors in the code:
The array initialization should not include the size if the elements are specified.
The loop condition should use
<
instead of
<=
to avoid an IndexOutOfRangeException.
public class Program
{
public static void Main(string[] args)
{
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
}
}
(Basic)
public class Program
{
public static void Main(string[] args)
{
string input = "racecar";
bool isPalindrome = IsPalindrome(input);
Console.WriteLine($"Is the string '{input}' a palindrome? {isPalindrome}");
}
public static bool IsPalindrome(string input)
{
int left = 0;
int right = input.Length - 1;
while (left < right)
{
if (input[left] != input[right])
{
return false;
}
left++;
right--;
}
return true;
}
}
(Basic)
public class Program
{
public static void Main(string[] args)
{
int x = 10;
int y = x++;
Console.WriteLine($"x: {x}, y: {y}");
}
}
The output will be:
x: 11, y: 10
Explanation:
x++
is a post-increment operator, which means the current value of
x
(10) is assigned to
y
, and then
x
is incremented by 1.
(Basic)
public class Program
{
public static void Main(string[] args)
{
string[] fruits = { "Apple", "Banana", "Cherry" };
foreach (string fruit in fruits)
{
fruit = fruit.ToUpper();
}
Console.WriteLine(string.Join(", ", fruits));
}
}
Expected Output:
APPLE, BANANA, CHERRY
The error is that the
fruit
variable inside the
foreach
loop is a copy, and modifying it does not affect the elements in the array. Use a
for
loop to modify the array elements.
public class Program
{
public static void Main(string[] args)
{
string[] fruits = { "Apple", "Banana", "Cherry" };
for (int i = 0; i < fruits.Length; i++)
{
fruits[i] = fruits[i].ToUpper();
}
Console.WriteLine(string.Join(", ", fruits));
}
}
(Intermediate)
public class Program
{
public static void Main(string[] args)
{
List numbers = new List { 1, 2, 3, 4, 5 };
for (int i = 0; i < numbers.Count; i++)
{
for (int j = 0; j < numbers.Count; j++)
{
if (i != j)
{
Console.WriteLine(numbers[i] * numbers[j]);
}
}
}
}
}
The nested loops cause the time complexity to be O(n^2). Since the multiplication of two numbers is commutative, we can reduce redundant calculations.
public class Program
{
public static void Main(string[] args)
{
List numbers = new List { 1, 2, 3, 4, 5 };
for (int i = 0; i < numbers.Count; i++)
{
for (int j = i + 1; j < numbers.Count; j++)
{
Console.WriteLine(numbers[i] * numbers[j]);
}
}
}
}
(Intermediate)
public class Program
{
public static void Main(string[] args)
{
int n = 100;
int sum = 0;
for (int i = 1; i <= n; i++)
{
sum += i * i;
}
Console.WriteLine(sum);
}
}
The performance can be improved using a mathematical formula for the sum of squares:
∑i=1^n i^2 = n(n + 1)(2n + 1) / 6
public class Program
{
public static void Main(string[] args)
{
int n = 100;
int sum = (n * (n + 1) * (2 * n + 1)) / 6;
Console.WriteLine(sum);
}
}
(Intermediate)
public class Program
{
public static void Main(string[] args)
{
int n = 10;
int result = Factorial(n);
Console.WriteLine(result);
}
public static int Factorial(int n)
{
if (n == 0 || n == 1)
return 1;
return n * Factorial(n - 1);
}
}
The recursive approach can be replaced with an iterative approach to improve performance and avoid stack overflow for large
n
.
public class Program
{
public static void Main(string[] args)
{
int n = 10;
int result = Factorial(n);
Console.WriteLine(result);
}
public static int Factorial(int n)
{
int result = 1;
for (int i = 2; i <= n; i++)
{
result *= i;
}
return result;
}
}
(Intermediate)
public class Program
{
public static void Main(string[] args)
{
string s = "Hello";
string t = s;
s = s + " World";
Console.WriteLine($"s: {s}, t: {t}");
}
}
Answer: The output will be:
s: Hello World, t: Hello
(Advanced)
public class Program
{
public static void Main(string[] args)
{
int[] numbers = { 1, 2, 3, 4, 5, 1 };
bool hasDuplicates = HasDuplicates(numbers);
Console.WriteLine(hasDuplicates);
}
public static bool HasDuplicates(int[] numbers)
{
for (int i = 0; i < numbers.Length; i++)
{
for (int j = i + 1; j < numbers.Length; j++)
{
if (numbers[i] == numbers[j])
{
return true;
}
}
}
return false;
}
}
Using a
HashSet
to track seen elements can improve performance by reducing the time complexity to O(n).
public class Program
{
public static void Main(string[] args)
{
int[] numbers = { 1, 2, 3, 4, 5, 1 };
bool hasDuplicates = HasDuplicates(numbers);
Console.WriteLine(hasDuplicates);
}
public static bool HasDuplicates(int[] numbers)
{
HashSet seenNumbers = new HashSet();
foreach (int number in numbers)
{
if (!seenNumbers.Add(number))
{
return true;
}
}
return false;
}
}
(Advanced)
public class Program
{
public static void Main(string[] args)
{
int[] numbers = { 1, 5, 2, 9, 7 };
int secondLargest = FindSecondLargest(numbers);
Console.WriteLine($"Second largest element: {secondLargest}");
}
public static int FindSecondLargest(int[] numbers)
{
if (numbers.Length < 2)
throw new ArgumentException("Array must contain at least two elements.");
int largest = int.MinValue;
int secondLargest = int.MinValue;
foreach (int number in numbers)
{
if (number > largest)
{
secondLargest = largest;
largest = number;
}
else if (number > secondLargest && number != largest)
{
secondLargest = number;
}
}
return secondLargest;
}
}
Request question
Please fill in the form below to submit your question.
Overview of C#