C#
Generics
A generic collection is strongly typed (type safe), meaning that you can only put one type of object into it. This eliminates type mismatches at runtime. Another benefit of type safety is that performance is better with value type objects because they don't incur overhead of being converted to and from type object.
Delegates
A delegate(known as function pointer in C/C++) is a references type that invokes single/multiple method(s) through the delegate instance. It holds a reference of the methods. Delegate types are sealed and immutable type.
Delegates are like C++ function pointers but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
delegate int NumberChanger(int n);namespace DelegateAppl{ class TestDelegate { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return num; } public static int getNum() { return num; } static void Main(string[] args) { //create delegate instances NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); //calling the methods using the delegate objects nc1(25); Console.WriteLine("Value of Num: {0}", getNum()); nc2(5); Console.WriteLine("Value of Num: {0}", getNum()); Console.ReadKey(); } }}
delegate int NumberChanger(int n);namespace DelegateAppl{ class TestDelegate { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return num; } public static int getNum() { return num; } static void Main(string[] args) { //create delegate instances NumberChanger nc; NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); nc = nc1; nc += nc2; //calling multicast nc(5); Console.WriteLine("Value of Num: {0}", getNum()); Console.ReadKey(); } }}
Events are user actions such as key press, clicks, mouse movements, etc., or some occurrence such as system generated notifications. Applications need to respond to events when they occur. For example, interrupts. Events are used for inter-process communication.
Async and await
How Requests Are Processed by the Thread Pool
On the web server, the .NET Framework maintains a pool of threads that are used to service ASP.NET requests. When a request arrives, a thread from the pool is dispatched to process that request. If the request is processed synchronously, the thread that processes the request is busy while the request is being processed, and that thread cannot service another request.
This might not be a problem, because the thread pool can be made large enough to accommodate many busy threads. However, the number of threads in the thread pool is limited (the default maximum for .NET 4.5 is 5,000). In large applications with high concurrency of long-running requests, all available threads might be busy. This condition is known as thread starvation. When this condition is reached, the web server queues requests. If the request queue becomes full, the web server rejects requests with an HTTP 503 status (Server Too Busy). The CLR thread pool has limitations on new thread injections. If concurrency is bursty (that is, your web site can suddenly get a large number of requests) and all available request threads are busy because of backend calls with high latency, the limited thread injection rate can make your application respond very poorly. Additionally, each new thread added to the thread pool has overhead (such as 1 MB of stack memory). A web application using synchronous methods to service high latency calls where the thread pool grows to the .NET 4.5 default maximum of 5, 000 threads would consume approximately 5 GB more memory than an application able the service the same requests using asynchronous methods and only 50 threads. When you're doing asynchronous work, you're not always using a thread. For example, when you make an asynchronous web service request, ASP.NET will not be using any threads between the asyncmethod call and the await. Using the thread pool to service requests with high latency can lead to a large memory footprint and poor utilization of the server hardware.
Processing Asynchronous Requests
In web applications that sees a large number of concurrent requests at start-up or has a bursty load (where concurrency increases suddenly), making these web service calls asynchronous will increase the responsiveness of your application. An asynchronous request takes the same amount of time to process as a synchronous request. For example, if a request makes a web service call that requires two seconds to complete, the request takes two seconds whether it is performed synchronously or asynchronously. However, during an asynchronous call, a thread is not blocked from responding to other requests while it waits for the first request to complete. Therefore, asynchronous requests prevent request queuing and thread pool growth when there are many concurrent requests that invoke long-running operations.
Choosing Synchronous or Asynchronous Action Methods
This section lists guidelines for when to use synchronous or asynchronous action methods. These are just guidelines; examine each application individually to determine whether asynchronous methods help with performance.
In general, use synchronous methods for the following conditions:
The operations are simple or short-running.
Simplicity is more important than efficiency.
The operations are primarily CPU operations instead of operations that involve extensive disk or network overhead. Using asynchronous action methods on CPU-bound operations provides no benefits and results in more overhead.
In general, use asynchronous methods for the following conditions:
You're calling services that can be consumed through asynchronous methods, and you're using .NET 4.5 or higher.
The operations are network-bound or I/O-bound instead of CPU-bound.
Parallelism is more important than simplicity of code.
You want to provide a mechanism that lets users cancel a long-running request.
When the benefit of switching threads out weights the cost of the context switch. In general, you should make a method asynchronous if the synchronous method waits on the ASP.NET request thread while doing no work. By making the call asynchronous, the ASP.NET request thread is not stalled doing no work while it waits for the web service request to complete.
C#
namespace AsyncAwaitExample { class Program { static void Main() { var demo = new AsyncAwaitDemo(); demo.DoStuff(); while (AsyncAwaitDemo.vari) { Console.WriteLine("Doing Stuff on the Main Thread..................."); } Console.ReadLine(); } } public class AsyncAwaitDemo { public static bool vari = true; public async Task DoStuff() { await Task.Run(() => { LongRunningOperation(); }); } private static async Task<string> LongRunningOperation() { int counter; for (counter = 0; counter < 50000; counter++) { Console.WriteLine(counter); } if (counter == 50000) { vari = false; } return "Counter = " + counter; } } }
static void Main(string[] args) {
var read1 = ReadFileAsync(@"c:\somefile.txt ");
var read2 = ReadFileAsync(@"c:\someotherfile.txt ");
Task.WhenAll(read1, read2)
.ContinueWith(task => Console.WriteLine("All files have been read successfully."));
//do other work here while files are read...
Console.ReadLine();
}
Using Delegates with Events
The events are declared and raised in a class and associated with the event handlers using delegates within the same class or some other class. The class containing the event is used to publish the even
Passing Reference-Type Parameters by Val
The following example demonstrates passing a reference-type parameter, arr, by value, to a method, Change. Because the parameter is a reference to arr, it is possible to change the values of the array elements. However, the attempt to reassign the parameter to a different memory location only works inside the method and does not affect the original variable, arr.
C#
class PassingRefByVal { static void Change(int[] pArray) { pArray[0] = 888; // This change affects the original element. pArray = new int[5] {-3, -1, -2, -3, -4}; // This change is local. System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]); } static void Main() { int[] arr = {1, 4, 5}; System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]); Change(arr); System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]); } } /* Output: Inside Main, before calling the method, the first element is: 1 Inside the method, the first element is: -3 Inside Main, after calling the method, the first element is: 888 */
Passing Reference-Type Parameters by Ref
The following example is the same as the previous example, except that the ref keyword is added to the method header and call. Any changes that take place in the method affect the original variable in the calling program.
C#
class PassingRefByRef { static void Change(ref int[] pArray) { // Both of the following changes will affect the original variables: pArray[0] = 888; pArray = new int[5] {-3, -1, -2, -3, -4}; System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]); } static void Main() { int[] arr = {1, 4, 5}; System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]); Change(ref arr); System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]); } } /* Output: Inside Main, before calling the method, the first element is: 1 Inside the method, the first element is: -3 Inside Main, after calling the method, the first element is: -3 */
Swapping strings is a good example of passing reference-type parameters by reference. In the example, two strings,str1 and str2, are initialized in Main and passed to the SwapStrings method as parameters modified by the refkeyword. The two strings are swapped inside the method and inside Main as well.
C#
namespace ConsoleApplication1 { class Person { public int age; } class Program { static void Square(Person a, Person b) { a.age = a.age * a.age; b.age = b.age * b.age; Console.WriteLine(a.age + " " + b.age); } static void Main(string[] args) { Person p1 = new Person(); Person p2 = new Person(); p1.age = 5; p2.age = 10; Console.WriteLine(p1.age + " " + p2.age); Square(p1, p2); Console.WriteLine(p1.age + " " + p2.age); Console.ReadLine(); } } } ////The output would look like this: ////5 10 ////25 100 ////25 100
Difference between For and Foreach Loop in C#
The for loop executes a statement or a block of statements repeatedly until a specified expression evaluates to false.
There is need to specify the loop bounds( minimum or maximum).
The foreach statement repeats a group of embedded statements for each element in an array or an object collection. You do not need to specify the loop bounds minimum or maximum.
int j = 0;
for (int i = 1; i <= 5; i++)
{
j = j + i ;
}
int j = 0;
int[] myArr = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in myArr )
{
j = j + i ;
}
foreach: Treats everything as a collection and reduces the performance. foreach creates an instance of an enumerator (returned from GetEnumerator()) and that enumerator also keeps state throughout the course of the foreach loop. It then repeatedly calls for the Next() object on the enumerator and runs your code for each object it returns.
Using for loop we iterate the array in both direction, that is from index 0 to 9 and from 9 to 0.
But using for-each loop, the iteration is possible in forward direction only.
In variable declaration, foreach has five variable declarations (three Int32 integers and two arrays of Int32) while for has only three (two Int32 integers and one Int32 array).
When it goes to loop through, foreach copies the current array to a new one for the operation. While fordoesn't care of that part.
Interviewer asked me 2 scenario based question in one interview:
for (int i = 1; i <= 5; i++)
{
i = i + i;
}
The above code will work?
Yes this will work.
int[] tempArr = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in tempArr)
{
i = i + 1;
}
Above code will work?
This code will not compile. I have pasted screenshot of error.
Foreach loop
Foreach loop runs upon a single thread and processing takes place sequentially one by one. Foreachloop is a basic feature of C# and it is available from C# 1.0. Its execution is slower than Parallel.Foreach in most of the cases.
Parallel.ForEach loop
Parallel.ForEach loop runs upon multiple threads and processing takes place in a parallel way. Parallel.ForEach loop is not a basic feature of C# and it is available from C# 4.0 and above. Before C# 4.0 we cannot use it. Its execution is faster than foreach in most of the cases. To use Parallel.ForEach loop we need to import System.Threading.Tasks namespace in using directive.
Difference between destructor, dispose and finalize method?
Destructors
Destructors cannot be defined in structs. They are only used with classes.
A class can only have one destructor.
Destructors cannot be inherited or overloaded.
Destructors cannot be called. They are invoked automatically.
A destructor does not take modifiers or have parameters.
For example, the following is a declaration of a destructor for the class Car:
C#
class Car { ~Car() // destructor { // cleanup statements... } }
The destructor implicitly calls Finalize on the base class of the object. Therefore, the previous destructor code is implicitly translated to the following code:
protected override void Finalize() { try { // Cleanup statements... } finally { base.Finalize(); } }
This means that the Finalize method is called recursively for all instances in the inheritance chain, from the most-derived to the least-derived.
Destructor
They are special methods that contains clean up code for the object. You can not call them explicitly in your code as they are called implicitly by GC. In C# they have same name as the class name preceded by the ~ sign. Like-
Class MyClass{~MyClass(){.....}}
In VB.NET, destructors are implemented by overriding the Finalize method of the System.Object class.
Dispose
These are just like any other methods in the class and can be called explicitly but they have a special purpose of cleaning up the object. In the dispose method we write clean up code for the object. It is important that we freed up all the unmanaged recources in the dispose method like database connection, files etc. The class implementing dispose method should implement IDisposable interface.A Dispose method should call the GC.SuppressFinalize method for the object it is disposing if the class has desturctor because it has already done the work to clean up the object, then it is not necessary for the garbage collector to call the object's Finalize method.
Finalize
A Finalize method acts as a safeguard to clean up resources in the event that your Dispose method is not called. You should only implement a Finalize method to clean up unmanaged resources. You should not implement a Finalize method for managed objects, because the garbage collector cleans up managed resources automatically. Finalize method is called by the GC implicitly therefore you can not call it from your code.
Note: In C#, Finalize method can not be override, so you have to use destructor whose internal implementation will override the Finalize method in MSIL.But in the VB.NET, Finalize method can be override because it does support destructor method.
Static Constructors ,Private Constructors :
A private constructor is a special instance constructor. It is generally used in classes that contain static members only. If a class has one or more private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class. For example:
C#
class NLog { // Private Constructor: private NLog() { } public static double e = Math.E; //2.71828... }
The declaration of the empty constructor prevents the automatic generation of a default constructor. Note that if you do not use an access modifier with the constructor it will still be private by default. However, the private modifier is usually used explicitly to make it clear that the class cannot be instantiated.
Private constructors are used to prevent creating instances of a class when there are no instance fields or methods, such as the Math class, or when a method is called to obtain an instance of a class. If all the methods in the class are static, consider making the complete class static.
// If you uncomment the following statement, it will generate // an error because the constructor is inaccessible: // NLog obj= new NLog (); // Error
But, if a class has other public constructors, then that can be instantiated. A class can have multiple private constructor and can call it by another constructor.
For example:-
Class A
{
int a;
private A()
{
}
public A(int b) : A() // Calling private constructor by another constructor.
{
this.a=b;
}
}
A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced.
C#
class SimpleClass { // Static variable that must be initialized at run time. static readonly long baseline; // Static constructor is called at most one time, before any // instance constructor is invoked or member is accessed. static SimpleClass() { baseline = DateTime.Now.Ticks; } }
Static constructors have the following properties:
A static constructor does not take access modifiers or have parameters.
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
A static constructor cannot be called directly.
The user has no control on when the static constructor is executed in the program.
A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.
A class can have only one static constructor.
What is the difference between final, finally and finalize?
Final:- It is used in the following cases:
If the final keyword is attached to a variable then the variable becomes constant i.e. its value cannot be changed in the program.
If a method is marked as final then the method cannot be overridden by any other method.
If a class is marked as final then this class cannot be inherited by any other class.
If a parameter is marked with final it becomes a read only parameter.
Finally:-
If an exception is thrown in try block then the control directly passes to the catch block without executing the lines of code written in the remainder section of the try block.
In case of an exception we may need to clean up some objects that we created. If we do the clean-up in try block, they may not be executed in case of an exception.
Thus finally block is used which contains the code for clean-up and is always executed after the try ...catch block.
Finalize:-
It is a method present in a class which is called before any of its object is reclaimed by the garbage collector. finalize() method is used for performing code clean-up before the object is reclaimed by the garbage collector.
Constant
Constant fields or local variables must be assigned a value at the time of declaration and after that they cannot be modified. By default constant are static, hence you cannot define a constant type as static.
ReadOnly
A readonly field can be initialized either at the time of declaration or with in the constructor of same class. Therefore, readonly fields can be used for run-time constants.
Static
The static keyword is used to specify a static member, which means static members are common to all the objects and they do not tied to a specific object. This keyword can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, destructors, or types other than classes.
Key points about Static keyword
If the static keyword is applied to a class, all the members of the class must be static.
Static methods can only access static members of same class. Static properties are used to get or set the value of static fields of a class.
Static constructor can't be parameterized. Access modifiers can not be applied on Static constructor, it is always a public default constructor which is used to initialize static fields of the class.
New Keyword
New keyword is also used in polymorphism concept, but in the case of method overloading So what does overloading means, in simple words we can say procedure of hiding your base class through your derived class.
To hide base class methods in derived classes without having any warning messages we can declare derived class methods with new keyword.
It is implemented as:
Hide Copy Code
class A { public void show() { Console.WriteLine("Hello: Base Class!"); Console.ReadLine(); } } class B : A { public new void show() { Console.WriteLine("Hello: Derived Class!"); Console.ReadLine(); } }
Virtual Keyword
Virtual keyword is used for generating a virtual path for its derived classes on implementing method overriding. Virtual keyword is used within a set with override keyword. It is used as:
Override Keyword
Override keyword is used in the derived class of the base class in order to override the base class method.Override keyword is used with virtual keyword, as:
// Base Class class A { public virtual void show() { Console.WriteLine("Hello: Base Class!"); Console.ReadLine(); } } // Derived Class class B : A { public override void show() { Console.WriteLine("Hello: Derived Class!"); Console.ReadLine(); } }
Static Class: Declared with Static keyword, methods in Static Class are also static along with variables of the class.This class cannot be instantiated,
i.e we cannot have objects of this class. To access methods of this class, you can directly use classname.method. Also this class cannot be inherited.
Sealed Class: Declared with Sealed keyword, which enables this class to seal all its variables, methods and properties. No other class can inherit anything from this class or in other words,
this class cannot be inherited. But we can instantiate this class, i.e we can have any number of objects of a sealed class. sealed class can not be inherited in other words, no class can be derived from the sealed class.
Basically used for commercial reasons where restrictions are implemented on the class so that no one use the existing class and derive from it without the license.
If a method is declared as sealed it can not be overridden. Used to avoid instability of some major code.
Abstract Class : A class that contains atleast one abstract method and uses a keyword abstract is a abstract class. It may or may not have the non abstract methods. This class can be inherited.
Abstract method means that the method does not have any implementation..it just contains the signature of method. The abstract method is required to be implemented in the derived class.
Partial Class
A class defined in two or more files is called a partial class. The keyword partial is used to define the class. When working on large projects, spreading a class over separate files allows multiple programmers to work on it simultaneously. During compile time all the partial class are compiled into one type only.
IEnumerable Interface : Exposes an enumerator, which supports a simple iteration over a non-generic collection.
IEnumerable has one method GetEnumerator() which allows one to read through the values in a collection but not write to it. Most of the complexity of using the enumerator is taken care of for us by the for each statement in C#. IEnumerable has one property: Current, which returns the current element.
ICollection implements IEnumerable and adds few additional properties the most use of which is Count. The generic version of ICollection implements the Add() and Remove() methods.
IList implements both IEnumerable and ICollection.
ICollection inherits from IEnumerable. There is one difference:
you can find IEnumerable[ i ] --> Index Based
you can NOT find ICollection[ i ] --> Not Index Based
IEnumerable interface is used when we want to iterate among our classes using a foreach loop. The IEnumerable interface has one method, GetEnumerator, that returns an IEnumerator interface that helps us to iterate among the class using the foreach loop.
It provides read-only access to collections. We cannot change any item inside an IEnumerable List.
ICollection Interface
Defines methods to manipulate generic collections.The ICollection interface is inherited from the IEnumerable interface which means that any class that implements the ICollection interface can also be enumerated using a foreach loop. In the IEnumerable interface we don't know how many elements there are in the collection whereas the ICollection interface gives us this extra property for getting the count of items in the collection. The ICollection interface contains the following:
Count Property
IsSynchronized Property
SyncRoot Property
CopyTo Method
The Count property is used for maintaining the count of elements in the list whereas the IsSysnchronized and SyncRoot properties help to make the collection thread-safe. The CopyTo method copies the entire collection into an array.
The generic version of this interface provides Add and Remove methods also.
IList Interface
The IList interface implements both ICollection and IEnumerable interfaces. This interface allows us to add items to and remove items from the collection. It also provides support for accessing the items from the index. This interface has more power than the preceding two interfaces.The IList interface has one indexer by which we can access any element by its position and can insert an element and remove an element at any position.
//IList {indexer and Modify} vs ICollection {randomly and Modify} //Collection can not be instantiate from ICollection , so it should be instantiate from List System.Collections.Generic.ICollection<string> strICollection = new List<string>();
yield
“Yield keyword helps us to do custom stateful iteration over .NET collections.”
There are two scenarios where “yield” keyword is useful:-
Customized iteration through a collection without creating a temporary collection.
Stateful iteration.
When you use the yield keyword in a statement, you indicate that the method, operator, or get accessor in which it appears is an iterator.
You consume an iterator method by using a foreach statement or LINQ query. Each iteration of the foreach loop calls the iterator method. When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator function is called.
C#
public class PowersOf2 { static void Main() { // Display powers of 2 up to the exponent of 8: foreach (int i in Power(2, 8)) { Console.Write("{0} ", i); } } public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent) { int result = 1; for (int i = 0; i < exponent; i++) { result = result * number; yield return result; } } // Output: 2 4 8 16 32 64 128 256 }