C# Interview Questions

;
Filters
Tag Filters
Level
votes
2
answers
1
Answer

When you use the var keyword, you tell the compiler to automatically determine the type of the variable based on the value assigned.

When you use the dynamic keyword you tell the compiler to turn off compile-time checking. However the type checks still do happen during runtime, and instead of compile time errors, you get runtime errors.

The following code won't compile as the compiler has inferred the value of v to be string, and ++ is not defined for a string.

var v = "some string"; //compiler infers type of v is string
v++; // compiler error here. The code does not compile.

The below code compiles fine as the compiler checks are turned off for dynamic. However if we run it, we will get a Runtime exception when we attempt to increment a string.

dynamic d = "some string"
d++;

For var the type of the variable is determined at the time of declaration and the type does not change throughout the lifetime of the variable. However for a variable declared using the dynamic keyword, the variable can assume different underlying types.

dynamic d = "some string"; // d is string
d = 100; // d is now int

With dynamic we lose compile time checks, so it is generally advised to avoid using dynamics unless necessary. Following quote from MSDN nicely summarized when use of dynamics is justified:

As a developer, you use the dynamic keyword with variables expected to contain objects of uncertain type such as objects returned from a COM or DOM API; obtained from a dynamic language (IronRuby, for example); from reflection; from objects built dynamically in C# 4.0 using the new expand capabilities.

votes
2
answers
1
Can we have memory leaks in a .Net Application?
Maverick 12/29/2014 4:23 PM
Beginner
.net
c#
Answer
Though .Net has automatic memory management and it does a good job in freeing up objects not in use, there is still a possibility of a memory leak when unwanted references linger around indefinitely or when unmanaged resources are not disposed off. Following are a few examples:

Subscriptions to Event Handlers

Consider the following code:
var shortLivedObject = new ShortLivedObject();
mainForm.SomeEvent += shortLivedObject.HandleSomeEvent;
Now say after a short while shortLivedObject is not needed and is either disposed off or goes out of scope and there are no other variables pointing to this instance. We would then expect the garbage collector to free up the memory allocated for it when it runs. However Garbage Collector is unable to do so as mainForm.SomeEvent still has an active reference to this instance (more specifically the handler which resides in this instance). So it cannot clean it up till the mainForm object is destroyed. We have a leak. 

To avoid this we must unsubscribe to this event (mainForm.SomeEvent -= shortLivedObject.HandleSomeEvent). A better practice is to use weak event pattern. See here for more details.

Unmanaged Memory Leak

In C# you can allocate unmanged memory. If you do so you must free it explicitly or else you will have a memory leak. Garbage Collector can only manage the managed heap.
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(someObject));
The memory allocated by the above statement will remain allocated throughout the life of the application, unless you call
Marshal.FreeHGlobal(ptr);


Other Instances of Leak


If your object lives longer than expected even after multiple garbage collection cycles, you have a potential memory leak. There could be numerous scenarios of this and would be very specific to the code you are writing. E.g. suppose you are having a static list of objects. If you add an object to this list you must also remove it once it is no longer required. If you forget to remove it, or some exception causes it to be not getting removed from the list, you are introducing a memory leak.

Some people classify not calling the dispose method of an IDisposable object (e.g Streams etc) as introducing a memory leak. These are not exactly memory leaks as when the garbage collector runs it will call dispose and clean up the object. Nevertheless you should always call Dispose() on disposable objects (or use using statement), to avoid performance degradation. 

votes
1
answers
1
Answer

Superficially, both interfaces and abstract classes are look similar, but there are a few important differences:

An interface is a contract, and any class which implements the interface has to abide by the contract by providing an implementation of the methods and/or properties which the interface declares. An interface cannot contain any code. A class can implement any number of interfaces.


An 
abstract class is a class which cannot be instantiated. It contains at least one abstract method (method with no definition) or property and can contain members and other function definitions like a normal class (in c# a class can be marked as abstract even if it doesnt have any abstract members). A class cannot implement more than one class (abstract or not).

votes
1
answers
1
Answer
A client calling a normal wcf void function (request/response) has to wait for the server to finish the call. So the client blocks until the server finishes executing the code and sends back HTTP 200 Status code (OK) to the client.

A OneWay operation gets finished as soon as the server receives the message and sends an acknowledgement (HTTP 202). The client does not have to wait for the call on the server to finish.

This makes OneWay operations more scalable as compared to normal operations (even if they are called asynhronously)
votes
2
answers
1
Answer

Interlocked class provides a set of static functions which allow a few simple operations to be performed thread safe. Apart from convenience, these functions are much faster than having a lock around an equivalent statement (explained below). First, following is a list of Interlocked functions with explanation in comments.

long counter = 0;
            
//Increment counter by 1
Interlocked.Increment (ref counter);                              
 
//Decrement counter by 1
Interlocked.Decrement (ref counter);                              
 
//Add 10 to counter
Interlocked.Add (ref counter, 10);                                 
 
//Set counter = 100 and return the original value of counter before it was changed.
//This usually does not require a lock but consider a scenario where
//counter is a 64 bit value and code running on a 32 bit machine.
//In such a scenario the assignment happens in 2 steps for each 32 bit part
//and hence the assignment is not atomic.
var oldCounterValue = Interlocked.Exchange (ref counter, 100);

// Read a 64-bit value atomically into another variable (val)
var val = Interlocked.Read(ref counter);               
 
// Set counter = 999 if counter == 1000
Interlocked.CompareExchange(ref counter, 999, 1000);  

As I mentioned these statements are faster in most cases and especially on modern CPUs, as these functions execute in a lock free manner or as a single instruction wherever possible, thus avoiding the need for a lock (they do use memory barriers though, to avoid reordering issues etc.) For example CompareExchange function uses the cpu instruction CMPXCHG which allows Comparison and Exchange of values in a single instruction which cannot be pre-empted.

Next Page > < Previous Page