• C# language versioning
  • How to achieve multiple inheritances in C#?
  • What is static class in c#
  • What is a field in CSharp?
  • What is a generic class in csharp?
  • Multicast Delegates
  • Indexers
  • Object Pool
  • Difference between var and dynamic
  • Anonymous Types - C#
  • Anonymous Methods- C#
  • ReadOnly Vs Const Keyword c#
  • Sealed vs Abstract class C#
  • Can multiple catch blocks be executed?
  • What is the difference between public, static, and void?
  • What is an object?
  • Define Constructors
  • What is Jagged Arrays?
  • What is the difference between ref & out parameters?
  • What is the use of 'using' statement in C#?
  • What is serialization?
  • What are Custom Control and User Control?
  • What are sealed classes in C#?
  • What is the difference between Array and Arraylist?
  • System.String vs System.Text.StringBuilder classes?
  • System.Array.CopyTo() vs System.Array.Clone() ?
  • How can we sort the elements of the Array in descending order?
  • Write down the C# syntax to catch an exception
  • What are circular references?
  • List down the commonly used types of exceptions in .NET
  • What are Custom Exceptions?
  • How do you inherit a class into other class in C#?
  • What is the base class in .net from which all the classes are derived from?
  • How to use nullable types in .NET?
  • How we can create an array with non-default values?
  • What is difference between "is" and "as" operators in c#?
  • What is difference between the "throw" and "throw ex" in .NET?
  • What are C# attributes and its significance?
  • How to implement a singleton design pattern in C#?
  • What is the difference between directcast and ctype?
  • Is C# code is managed or unmanaged code?
  • What is Console application?
  • What is Garbage Collection?
  • What are strong references and weak references in GC?
  • How GC come to know that object is ready to get collected?
  • What are generations in GC?
  • How value types get collected v/s reference types?
  • What is the difference between Finalize() and Dispose() methods?
  • Can we pin objects for later references?
  • Does GC work Web Application vs windows application?
  • How to Force Garbage Collection?
  • Why does Garbage Collection only sweep the heap?
  • Usage of Destructor
  • What is lazy initialization?

How to achieve multiple inheritances in C#?

  • You cannot inherit from multiple classesin c# by default.
  • But you may use interfaces or a combination of one class and interface(s), where interface(s) should be followed by class name in the signature.

Example:

    interface A
    { }
    interface B
    { }
    Class BaseClass {}
    class DerivedClass : A, B { } // from multiple Interface(s) 
    class DerivedClass : Base, B { } // from one Class and Interfacce(s)​ 

What is static class in c#

Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class

Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object.

The main features of a static class are:

You cannot call static methods using an object of the non-static class. The static methods can only call other static methods and access static members. You cannot access non-static members of the class in the static methods


What is a field in CSharp?

  • Properties expose fields.
  • Fields should (almost always) be kept private to a class and accessed via get and set properties.
  • Properties provide a level of abstraction allowing you to change the fields while not affecting the external way they are accessed by the things that use your class.

Example:

public class MyClass
{
    // this is a field.  It is private to your class and stores the actual data.
    private string _myField;

    // this is a property. When accessed it uses the underlying field,
    // but only exposes the contract, which will not be affected by the underlying field
    public string MyProperty
    {
        get
        {
            return _myField;
        }
        set
        {
            _myField = value;
        }
    }

    // This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
    // used to generate a private field for you
    public int AnotherProperty{get;set;} 
}

What is a generic class in csharp?

Generics are used to make reusable code classes to decrease the code redundancy, increase type safety, and performance.

Using generics, we can create collection classes. To create generic collection, System.Collections.Generic namespace should be used instead of classes such as ArrayList in the System.Collections namespace.

Generics promotes the usage of parameterized types.

  • Generic classes encapsulate operations that are not specific to a particular data type.
  • The most common use for generic classes is with collections like linked lists, hash tables, stacks, queues, trees, and so on.
  • Operations such as adding and removing items from the collection are performed in basically the same way regardless of the type of data being stored.

Example:

class BaseNodeGeneric<T> { }

Multicast Delegates

​How to combine delegates (Multicast Delegates)

A delegate having multiple handlers assigned to it is called multicast delegate.
Each handler is assigned to a method.

Example

C#Copy

using System;

// Define a custom delegate that has a string parameter and returns void.
delegate void CustomDel(string s);

class TestClass
{
    // Define two methods that have the same signature as CustomDel.
    static void Hello(string s)
    {
        Console.WriteLine($"  Hello, {s}!");
    }

    static void Goodbye(string s)
    {
        Console.WriteLine($"  Goodbye, {s}!");
    }

    static void Main()
    {
        // Declare instances of the custom delegate.
        CustomDel hiDel, byeDel, multiDel, multiMinusHiDel;

        // In this example, you can omit the custom delegate if you
        // want to and use Action<string> instead.
        //Action<string> hiDel, byeDel, multiDel, multiMinusHiDel;

        // Create the delegate object hiDel that references the
        // method Hello.
        hiDel = Hello;

        // Create the delegate object byeDel that references the
        // method Goodbye.
        byeDel = Goodbye;

        // The two delegates, hiDel and byeDel, are combined to
        // form multiDel.
        multiDel = hiDel + byeDel;

        // Remove hiDel from the multicast delegate, leaving byeDel,
        // which calls only the method Goodbye.
        multiMinusHiDel = multiDel - hiDel;

        Console.WriteLine("Invoking delegate hiDel:");
        hiDel("A");
        Console.WriteLine("Invoking delegate byeDel:");
        byeDel("B");
        Console.WriteLine("Invoking delegate multiDel:");
        multiDel("C");
        Console.WriteLine("Invoking delegate multiMinusHiDel:");
        multiMinusHiDel("D");
    }
}
/* Output:
Invoking delegate hiDel:
  Hello, A!
Invoking delegate byeDel:
  Goodbye, B!
Invoking delegate multiDel:
  Hello, C!
  Goodbye, C!
Invoking delegate multiMinusHiDel:
  Goodbye, D!
*/

 


Indexers

Indexers are known as smart arrays in C#.

It allows the instances of a class to be indexed in the same way as an array.

Eg:

public int this[int index]    // Indexer declaration

Indexers allow instances of a class or struct to be indexed just like arrays. The indexed value can be set or retrieved without explicitly specifying a type or instance member. Indexers resemble properties except that their accessors take parameters.

The following example defines a generic class with simple get and set accessor methods to assign and retrieve values. The Program class creates an instance of this class for storing strings.

C#Copy

using System;

class SampleCollection<T>
{
   // Declare an array to store the data elements.
   private T[] arr = new T[100];

   // Define the indexer to allow client code to use [] notation.
   public T this[int i]
   {
      get { return arr[i]; }
      set { arr[i] = value; }
   }
}

class Program
{
   static void Main()
   {
      var stringCollection = new SampleCollection<string>();
      stringCollection[0] = "Hello, World";
      Console.WriteLine(stringCollection[0]);
   }
}
// The example displays the following output:
//       Hello, World.

Object Pool

Create an object pool by using a ConcurrentBag

An object pool is a container having objects ready to be used.
It tracks the object that is currently in use, total number of objects in the pool.
This reduces the overhead of creating and re-creating objects.

 

  • This example shows how to use a ConcurrentBag<T> to implement an object pool. Object pools can improve application performance in situations where you require multiple instances of a class and the class is expensive to create or destroy. When a client program requests a new object, the object pool first attempts to provide one that has already been created and returned to the pool. If none is available, only then is a new object created.The ConcurrentBag<T> is used to store the objects because it supports fast insertion and removal, especially when the same thread is both adding and removing items. This example could be further augmented to be built around a IProducerConsumerCollection<T>, which the bag data structure implements, as do ConcurrentQueue<T> and ConcurrentStack<T>.
  • Tip
  • This article defines how to write your own implementation of an object pool with an underlying concurrent type to store objects for reuse. However, the Microsoft.Extensions.ObjectPool.ObjectPool<T> type already exists under the Microsoft.Extensions.ObjectPool namespace. Consider using the available type before creating your own implementation, which includes many additional features.
  • Example

C#

  • using System;
    using System.Collections.Concurrent;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ObjectPoolExample
    {
        public class ObjectPool<T>
        {
            private readonly ConcurrentBag<T> _objects;
            private readonly Func<T> _objectGenerator;
    
            public ObjectPool(Func<T> objectGenerator)
            {
                _objectGenerator = objectGenerator ?? throw new ArgumentNullException(nameof(objectGenerator));
                _objects = new ConcurrentBag<T>();
            }
    
            public T Get() => _objects.TryTake(out T item) ? item : _objectGenerator();
    
            public void Return(T item) => _objects.Add(item);
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                using var cts = new CancellationTokenSource();
    
                // Create an opportunity for the user to cancel.
                _ = Task.Run(() =>
                {
                    if (char.ToUpperInvariant(Console.ReadKey().KeyChar) == 'C')
                    {
                        cts.Cancel();
                    }
                });
    
                var pool = new ObjectPool<ExampleObject>(() => new ExampleObject());
    
                // Create a high demand for ExampleObject instance.
                Parallel.For(0, 1000000, (i, loopState) =>
                {
                    var example = pool.Get();
                    try
                    {
                        Console.CursorLeft = 0;
                        // This is the bottleneck in our application. All threads in this loop
                        // must serialize their access to the static Console class.
                        Console.WriteLine($"{example.GetValue(i):####.####}");
                    }
                    finally
                    {
                        pool.Return(example);
                    }
    
                    if (cts.Token.IsCancellationRequested)
                    {
                        loopState.Stop();
                    }
                });
    
                Console.WriteLine("Press the Enter key to exit.");
                Console.ReadLine();
            }
        }
    
        // A toy class that requires some resources to create.
        // You can experiment here to measure the performance of the
        // object pool vs. ordinary instantiation.
        class ExampleObject
        {
            public int[] Nums { get; set; }
    
            public ExampleObject()
            {
                Nums = new int[1000000];
                var rand = new Random();
                for (int i = 0; i < Nums.Length; i++)
                {
                    Nums[i] = rand.Next();
                }
            }
    
            public double GetValue(long i) => Math.Sqrt(Nums[i]);
        }
    }

Difference between var and dynamic

Below are some differences between var and dynamic keyword in C#:

 

VAR DYNAMIC
It is introduced in C# 3.0. It is introduced in C# 4.0
The variables are declared using var keyword are statically typed. The variables are declared using dynamic keyword are dynamically typed.
The type of the variable is decided by the compiler at compile time. The type of the variable is decided by the compiler at run time.
The variable of this type should be initialized at the time of declaration. So that the compiler will decide the type of the variable according to the value it initialized. The variable of this type need not be initialized at the time of declaration. Because the compiler does not know the type of the variable at compile time.
If the variable does not initialized it throw an error. If the variable does not initialized it will not throw an error.
It support intelliSense in visual studio. It does not support intelliSense in visual studio
var myvalue = 10; // statement 1
myvalue = “GeeksforGeeks”; // statement 2
Here the compiler will throw an error because the compiler has already decided the type of the myvalue variable using statement 1 that is an integer type. When you try to assign a string to myvalue variable, then the compiler will give an error because it violating safety rule type.
dynamic myvalue = 10; // statement 1
myvalue = “GeeksforGeeks”; // statement 2
Here, the compiler will not throw an error though the type of the myvalue is an integer. When you assign a string to myvalue it recreates the type of the myvalue and accepts string without any error.
It cannot be used for properties or returning values from the function. It can only used as a local variable in function. It can be used for properties or returning values from the function.

Anonymous Types - C#

Anonymous types - C#

Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler.

You create anonymous types by using the new operator together with an object initializer

var v = new { Amount = 108, Message = "Hello" };  
  
// Rest the mouse pointer over v.Amount and v.Message in the following  
// statement to verify that their inferred types are int and string.  
Console.WriteLine(v.Amount + v.Message);  

 

Important Points:

  • It is derived from System.Object class and it is also a sealed class. So, the properties of anonymous type are read-only means you cannot change their values.
  • It also has intellisense support in Visual Studio.
  • It can contain one or more read-only properties.
  • It does not contain class members such as events, methods, etc.
  • The expression that used to initialize properties are not null, anonymous method, or a pointer type.
  • You can also create an anonymous type array.
  • It cannot be cast to any other type except an object.
  • It is of reference type.
  • You are not allowed to create a field, property, event, or return type of a method is of anonymous type.
  • You are not allowed to declare formal parameters of a method, property, constructor, indexer as a anonymous type.
  • The scope of the anonymous type is always limited to the method in which they are defined. Due to their local scope, you are not allowed to pass an anonymous type to another method, but you can pass it to those methods which can accept dynamic type parameters. As shown in the below example.

    Note: Generally, passing anonymous type using dynamic type is not recommended.


Anonymous Methods- C#

Anonymous Methods- C#

An anonymous function is an "inline" statement or expression that can be used wherever a delegate type is expected. You can use it to initialize a named delegate or pass it instead of a named delegate type as a method parameter.

You can use a lambda expression or an anonymous method to create an anonymous function. We recommend using lambda expressions as they provide more concise and expressive way to write inline code. Unlike anonymous methods, some types of lambda expressions can be converted to the expression tree types.

class Test
{
    delegate void TestDelegate(string s);
    static void M(string s)
    {
        Console.WriteLine(s);
    }

    static void Main(string[] args)
    {
        // Original delegate syntax required
        // initialization with a named method.
        TestDelegate testDelA = new TestDelegate(M);

        // C# 2.0: A delegate can be initialized with
        // inline code, called an "anonymous method." This
        // method takes a string as an input parameter.
        TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); };

        // C# 3.0. A delegate can be initialized with
        // a lambda expression. The lambda also takes a string
        // as an input parameter (x). The type of x is inferred by the compiler.
        TestDelegate testDelC = (x) => { Console.WriteLine(x); };

        // Invoke the delegates.
        testDelA("Hello. My name is M and I write lines.");
        testDelB("That's nothing. I'm anonymous and ");
        testDelC("I'm a famous author.");

        // Keep console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Hello. My name is M and I write lines.
    That's nothing. I'm anonymous and
    I'm a famous author.
    Press any key to exit.
 */

 


ReadOnly Vs Const Keyword c#

ReadOnly Vs Const Keyword

READONLY KEYWORD
CONST KEYWORD
Read-only is used only when we want to assign the value at run time. Constant variables are declared and initialized at compile time. The value can't be changed afterward. 
In C#, readonly fields can be created using readonly keyword In C#, constant fields are created using const keyword.
ReadOnly is a runtime constant. Const is a compile time constant.
The value of readonly field can be changed. The value of the const field can not be changed.
It cannot be declared inside the method. It can be declared inside the method.
In readonly fields, we can assign values in declaration and in the contructor part. In const fields, we can only assign values in declaration part.
It can be used with static modifiers. It cannot be used with static modifiers.

 


Sealed vs Abstract class C#

Sealed vs Abstract  class C#

. Abstract Class  Sealed Class
Definition The abstract keyword enables you to create classes and class members that are incomplete and must be implemented in a derived class. The sealed keyword enables you to prevent the inheritance of a class or certain class members that were previously marked virtual.
     
 

Classes can be declared as abstract by putting the keyword abstract before the class definition. For example:

C#Copy

public abstract class A
{
    // Class members here.
}

An abstract class cannot be instantiated. The purpose of an abstract class is to provide a common definition of a base class that multiple derived classes can share. For example, a class library may define an abstract class that is used as a parameter to many of its functions, and require programmers using that library to provide their own implementation of the class by creating a derived class.

Abstract classes may also define abstract methods. This is accomplished by adding the keyword abstract before the return type of the method. For example:

C#Copy

public abstract class A
{
    public abstract void DoWork(int i);
}

Abstract methods have no implementation, so the method definition is followed by a semicolon instead of a normal method block. Derived classes of the abstract class must implement all abstract methods. When an abstract class inherits a virtual method from a base class, the abstract class can override the virtual method with an abstract method. For example:

C#Copy

// compile with: -target:library
public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}

public abstract class E : D
{
    public abstract override void DoWork(int i);
}

public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}

If a virtual method is declared abstract, it is still virtual to any class inheriting from the abstract class. A class inheriting an abstract method cannot access the original implementation of the method—in the previous example, DoWork on class F cannot call DoWork on class D. In this way, an abstract class can force derived classes to provide new method implementations for virtual methods.

Classes can be declared as sealed by putting the keyword sealed before the class definition. For example:

C#Copy

public sealed class D
{
    // Class members here.
}

A sealed class cannot be used as a base class. For this reason, it cannot also be an abstract class. Sealed classes prevent derivation. Because they can never be used as a base class, some run-time optimizations can make calling sealed class members slightly faster.

A method, indexer, property, or event, on a derived class that is overriding a virtual member of the base class can declare that member as sealed. This negates the virtual aspect of the member for any further derived class. This is accomplished by putting the sealed keyword before the override keyword in the class member declaration. For example:

C#Copy

public class D : C
{
    public sealed override void DoWork() { }
}