Basic .NET Framework – DOT NET Chapter Wise Interview Questions
Question 1:
What is an IL code?(B)What is a IL?
Answer:
IL code is a partially compiled code.
Note: Half compiled means this code is not yet compiled to machine/CPU (Central Processing Unit) specific instructions.
Question 2:
Why is IL code not fully compiled?
Answer:
We do not know in what kind of environment .NET code will run. In other words we do not know what can be the Operating System (OS), CPU configuration, machine configuration, security configuration, etc. So the IL code is half compiled and on run-time this code is compiled to machine specific using the environmental properties (CPU, OS, machine configuration etc).
Question 3:
Who compiles the IL code and how does it work?
Answer:
IL code is compiled by JIT (Just-in-time) compiler.
Question 4:
How does JIT compilation work?
Answer:
JIT compiles the code just before execution and then saves this translation in memory. Just before execution JIT can compile perfile, per function or a code fragment.
Question 5:
What are different types of JIT?(P)What are different types of JIT ?
Answer:
In Microsoft .NET there are three types of JIT compilers:
- Normal-JIT (Default): Normal-JIT compiles only those methods that are called at runtime. These methods are compiled the first time they are called, and then they are stored in cache. When the same methods are called again, the compiled code from cache is used for execution.
- Econo-JIT: Econo-JIT compiles only those methods that are called at runtime.. However, these compiled methods are not stored in cache so that RAM (Random Access Memory) can be utilized in an optimal manner.
- Pre-JIT: Pre-JIT compiles complete source code into native code in a single compilation cycle. This is done at the time of deployment of the application. We can implement Pre-JIT by using ngen.exe (The Native Image Generation).
Normal-JIT is the default implementation and it produces optimized code. Econo- JIT just replaces IL instruction with native counterpart. It does not do any kind of optimization. Econo- JIT does not store the compiled code in cache so it requires less memory.
The choice of Normal-JIT and Econo-JIT is decided internally. Econo-JIT is chosen when devices have limitation memory and CPU cycle issues like Windows CE powered device. When there is no memory crunch and CPU power is higher than Normal-JIT is used.
Pre-JIT is implemented by using ngen.exe which is explained in the next question.
Question 6:
What is Native Image Generator (Ngen.exe)?
Answer:
Ngen stores full compiled .NET native code into cache. In other words rather than dynamically compiling the code on runtime a full image of native compiled code is stored in cache while installing the application. This leads to better performance as the assembly loads and execute faster.
In order to install full compiled native code in cache we can execute the below command line from your Visual Studio command prompt.
ngen.exe install <assemblyname>
Question 7:
So does it mean that NGEN.EXE will always improve performance?
Answer:
No, it’s not always necessary that ngen.exe produces optimized code because it uses the current environments parameters which can change over a period of time. For instance a code compiled in Windows XP environment will not be the optimized code to run under Windows 2008 server. So we need to test once with ‘ngen’ and without ‘ngen’ to conclude if really the performance increases.
Question 8:
Is it possible to view the IL code?
Answer:
Yes by using ILDASM (IL Disassembler) simple tool we can view a IL code of a DLL (Dynamic Link Library) or EXE (Executable). In order to view IL code using ILDASM, go to Visual Studio command prompt and run “ILDASM.EXE”. Once ILDASM is running you can view the IL code.
Question 9:
What is a CLR?
Answer:
CLR (Common Language Runtime) is the heart of.NET framework and it does four primary tasks:
- Garbage collection
- CAS (Code Access Security)
- CV (Code Verification)
- IL to Native translation.
Note: There are many other uses of CLR but I have kept it short for interview point of view. In the further section we will explain these questions briefly.
Question 10:
What is the difference between managed and unmanaged code?
Answer:
Code that executes under CLR execution environment is called as managed code. LJnmanaged code executes outside CLR boundary. Unmanaged code is nothing but code written in C++, VB6, VC++, etc. Unmanaged codes have their own environment in which the code runs and it’s completely outside the control of CLR.
Question 11:
What is a garbage collector?
Answer:
Garbage collector is a feature of CLR which cleans unused managed (it does not clean unmanaged objects) objects and reclaims memory. It’s a background thread which runs continuously and at specific intervals it checks if there are any unused objects whose memory can be claimed.
Note: GC does not claim memory of unmanaged objects.
Note: Garbage collector is one of the very important interview topics due to complexity of generations, double GC loop because of destructor and the implementation of finalize and dispose pattern. So please go through the video of “What are Garbage collection, Generation, Finalize, Dispose and Idisposable?” to ensure that you understand the fundamentals clearly.
Question 12:
What are generations in Garbage Collector (Gen 0, Gen 1 and Gen 2)?
Answer:
Generations defines age of the object. There are three generations:
- Gen 0: When application creates fresh objects they are marked as Gen 0.
- Gen 1: When GC is not able to clear the objects from Gen 0 in first round it moves them to Gen 1 bucket.
- Gen 2: When GC visits Gen 1 objects and it is not able to clear them it moves them Gen 2.
Generations are created to improve GC performance. Garbage collector will spend more time on Gen 0 objects rather than Gen 1 and Gen 2 thus improving performance.
Note: More the objects in Gen 0, more your application is stable.
Question 13:
Garbage collector cleans managed code, how do we clean unmanaged code?
Answer:
Garbage collector only claims managed code memory. For unmanaged code you need to put clean up in destructor / finalize.
Question 14:
But when we create a destructor the performance falls down?
Answer:
Yes, when we define a destructor, garbage collector does not collect these objects in the first round. It moves them to Gen 1 and then reclaims these objects in the next cycle.
As more objects are created in Gen 1 the performance of the application falls down because more memory is consumed.
Question 15:
So how can we clean unmanaged objects and also maintain performance?
Answer:
We need to follow the below steps:
- Implement IDisposable interface and implement the Dispose
- In Dispose function calls the “GC. SuppressFinalize”
- At the client side ensure that the “Dispose” function is called when the object is no more required.
Below goes the code, this is also called as “Finalize and Dispose pattern”. This ensures that your objects are created in Gen 0 rather than Gen 1. “GC. SuppressFinalize” tells the garbage collector to not worry about destructor and destroy the objects in the first call itself.
class clsMyClass: IDisposable { ∼clsMyClass() { // In case the client forgets to call // Dispose, destructor will be invoked for Dispose(false); } protected virtual void Dispose(bool disposing) { if (disposing) { // Free managed objects. } // Free unmanaged objects } public void Dispose() { Dispose(true); // Ensure that the destructor is not called GC.SuppressFinalize(this); } }
Note: Please do go through the videos of “What is IDisposable interface and finalize dispose pattern in GC?’’in which we have actually showed how generation performance increases by using Finalize and Dispose pattern.
Question 16:
Can we force garbage collector to run?(l) Can we force garbage collector to run ?
Answer:
“System.GC .Collect ()” forces garbage collector to run. This is not a recommended practice but can be used if situations arise.
Question 17:
What is the difference between finalize and dispose?
Answer:
- Finalize is a destructor and Dispose is a function which is implemented via ‘ IDisposable’
- Finalize is non-deterministic, since it’s called by garbage collector. Dispose is a function and needs to be called by the client for clean up. In other Finalize is automatically called by garbage collector while Dispose needs to be called forcefully.
Note: As a good practice Finalize and Dispose are used collectively because of double garbage collector loop. You can talk about this small note. You can also talk about the above two differences.
Question 18:
What is CTS?
Answer:
In .NET there are lots of languages like C#, VB.NET, VF.NET, etc. There can be situations when we want code in one language to be called in other language. In order to ensure smooth communication between these languages the most important thing is that they should have a common type system. CTS (Common Types System) ensures that data types defined in two different languages get compiled to a common data type.
So “integer” data type in VB6 and i”int” datatype in C++ will be converted to System. int32, which is data type of CTS.
Note: If you know COM programming, you would know how difficult it is to interface VB6 application with VC++ application. As data type of both languages did not have a common ground where they can come and interface, by having CTS interfacing is smooth.
Question 19:
What is a CLS (Common Language Specification)?
Answer:
CLS is a subset of CTS. CLS is a specification or set of rules or guidelines. When any programming language adheres to these set of rules it can be consumed by any .NET language.
For instance one of the rule which makes your application CLS non-compliant is when you declare your methods members with same name and with only case differences in C#. You can try this. Create a simple class in C# with same name with only case differences and try to consume the same in VB.NET, it will not work.
Question 20:
What is an Assembly?
Answer:
Assembly is unit of deployment like EXE or a DLL.
Question 21:
What are the different types of Assembly?
Answer:
There are two types of assembly: Private and Public assembly. A private assembly is normally used by a single application, and is stored in the application’s directory, or a sub-directory beneath. A shared assembly is stored in the global assembly cache, which is a repository of assemblies maintained by the .NET runtime.
Shared assemblies are needed when we want the same assembly to be shared by various applications in the same computer.
Question 22:
What is Namespace?
Answer:
Namespace does two basic functionalities:
- It logically groups classes, for instance web.ui namespace logically groups Ul related features like textboxes, list control, etc.
- In Object Oriented world, many times it is possible that programmers will use the same class name. Qualifying NameSpace with class names avoids this collision.
Question 23:
What is difference between namespace and assembly?
Answer:
Following are the differences between namespace and assembly:
- Assembly is physical grouping of logical units, whereas namespace logically groups classes.
- Namespace can span multiple assemblies while assembly is a physical unit like EXE, DLL, etc.
Question 24:
What is ILDASM?
Answer:
ILDASM is a simple tool which helps you to view IL code of a DLL or EXE. In order to view IL code using ILDASM, go to Visual Studio command prompt and run “ILDASM.EXE”. Once ILDASM is running you view the IL code.
Question 25:
What is Manifest?
Answer:
Assembly metadata is stored in Manifest. Manifest contains metadata which describes the following things:
- Version of assembly
- Security identity
- Scope of the assembly
Resolve references to resources and classes The assembly manifest is stored in the DLL itself.
Question 26:
Where is the version information stored of an assembly?
Answer:
Version information is stored in assembly inside the manifest.
Question 27:
Is versioning applicable to private assemblies?
Answer:
Yes, versioning is applicable to private assemblies also.
Question 28:
What is the use of strong names?
Answer:
Note: This question can also be asked in two different ways: What are weak references and strong reference or How do you create strong name to a .NET assembly.
When we talk about .NET application it has two parts one is the class library or the DLL and the other the consumer like windows Ul, etc., using this DLL.
If the consumer identifies the DLL library by namespace and class names it’s called as weak reference. It’s very much possible in deployment environment someone can delete the original class library and fake a similar class library with the same class name and namespace name.
Strong name is a unique name which is produced by the combination of version number, culture information, public key and digital signature. No one can fake this identity or generate the same name.
So your consumer or Ul will refer the class library with strong names rather than class and namespace names. In order to create strong name, right click on the Class library, click on Properties, click on Signing* tab and click on the New menu to generate strong names as shown in the Figure 2.1.
Question 29:
What is Delay signing?
Answer:
The whole point about strong names is to ensure that the clients (Ul, External components, etc.) who is consuming the DLL knows that the DLL was published from a valid source. This authenticity is verified by using strong names. Strong name protection is good from external hackers but what if your own developers think of doing something mischievous.
That’s why delay signing helps. The strong name key has two keys: public key and private key. You only share the public key with your developers so that they can work seamlessly. The private key is stored in a secured location and when the DLL is about to be deployed on production the key is injected for further security.
Question 30:
What is GAC?
Answer:
GAC (Global Assembly Cache) is where all shared .NET assembly resides. GAC is used in the following situations:
- If the application has to be shared among several application which is in the same computer.
- If the assembly has some special security, requirements like only administrators can remove the assembly. If the assembly is private then a simple delete process of the assembly file will remove the assembly.
Question 31:
How to add and remove an assembly from GAC?
Answer:
You can use the ‘GacUtil’ tool which comes with Visual Studio. So to register an assembly into GAC go to “Visual Studio Command Prompt” and type “gacutil -i (assembly name)”, where (assembly name) is the DLL name of the project.
One you have installed the assembly the DLL can be seen in ‘c: \windows\assemblyV folder.
When we have many DLL’s to be deployed we need to create setup and deployment package using windows installer. So the common way of deploying GAC DLL in production is done by using windows installer.
Question 32:
If we have two versions of the same assembly in GAC how to we make a choice?
Answer:
When we have two versions of the same assembly in GAC we need to use binding redirect tag and specify the version we want to use in the new version property as shown in the below “app.config” file.
<configuration> <runtime> <assemblyBinding xmlns="urn: schemas-microsoft-com: asm.v1"> <dependentAssembly> <assemblyldentity name="ComputerName" publicKeyToken="cfc68d722cd6al64"/> <publisherPolicy apply="yes" /> <bindingRedirect oldVersion="1.1.0.0" newVersion="1.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
Question 33:
What is Reflection and why we need it?
Answer:
Reflection is needed when you want to determine / inspect contents of an assembly. For example, look at your Visual Studio Editor IntelliSense, when you type (dot) before any object, it gives you all members of the object. This is possible because of reflection.
Reflection also goes one step further; it can also invoke a member which is inspected. For instance if the reflection detects that there is a method called as “GetChanges” in an object as shown in Figure 2.2. We can get a reference to that method instance and invoke the same on runtime.
In simple words reflection passes through two steps:
“Inspect” and “Invoke” (optional) as shown in Figure 2.3.“Invoke” process is optional.
Question 34:
How do we implement reflection?
Answer:
Implementing reflection in C# is two step process, first get the “type” of the object and then use the type to browse members like “methods”, “properties”, etc.
Step 1: The first step is to get the type of the object. So for example you have a DLL called as “ClassLibrary1.dll” which has a class called as “Classl”. We can use the “Assembly” class (belongs to System.Reflection namespace) to get a reference to the type of the object. Later we can use “Activator.Createlnstance” to create an instance of the class. The “GetTypeO” function helps us to get reference to the type of the object.
var myAssembly = Assembly.LoadFile(@"C: \ClassLibraryl.dll"); var myType = myAssembly .GetType ("ClassLibraryl.Classl") ; dynamic objMyClass = Activator.Createlnstance(myType); // Get the class type Type parameterType = objMyClass.GetType();
Step 2: Once we have reference the type of the object we can then call “GetMembers” or “GetProperties” to browse through the methods and properties of the class.
// Browse through members foreach (MemberInfo objMemberlnfo in parameterType.GetMembers()) {Console.WriteLine(objMemberlnfo.Name);} // Browse through properties. foreach (Propertylnfo objPropertylnfo in parameterType.GetProperties()) {Console.WriteLine(obj Propertylnfo.Name);}
In case you want to invoke the member which you have inspected you can use “invokeMember” to invoke the method. Below is the code for the same.
parameterType.InvokeMember("Display",BindingFlags.Public| BindingFlags.NonPublic | BindingFlags.InvokeMethod| BindingFlags.Instance, null, objMyClass, null);
Question 35:
What are the practical uses of reflection?
Answer:
- If you are creating application like Visual Studio editors where you want show internal of an object by using IntelliSense.
- In unit testing sometimes we need to invoke private methods. It checks whether private members are proper or not.
- Sometimes we would like to dump properties, methods and assembly references to a file or probably show it on a screen.
Question 36:
What is the use of dynamic keyword?
Answer:
Programming languages can be divided into two categories strongly typed and dynamically typed. Strongly typed languages are those where the checks happen during compile-time while dynamic languages are those where type checks are bypassed during compile-time. In dynamic language object types are known only during runtime and type checks are activated only at runtime.
So we would like to take advantage of both the world. Because many times we do not know object type until the code is executed. In other words we are looking at something like dynamically statically typed kind of environment. That’s what dynamic keyword helps us with.
If you create a variable using the “dynamic” keyword and if you try to see members of that object you will get a message as shown in Figure 2.5 “This operation will be resolved at runtime”.
Now try the below code out. In the below code I have created a dynamic variable which is initialized with a string data. And in the second line I am trying to have fun by trying to execute a numeric
incremental operation. So what will happen now?…. think.
dynamic x = “c#”; x++;
Now this code will compile successfully. But during runtime it will throw an exception complaining that the mathematical operations cannot be executed on the variable as it is a string type as shown in Figure 2.6. In other words during runtime the dynamic object gets transformed from general data type to specific data type (ex: string for the below code).
Question 37:
What are practical uses of dynamic keyword?
Answer:
One of the biggest practical uses of dynamic keyword is when we operate on MS Office components via Interop.
So for example if we are accessing Microsoft Excel components without dynamic keyword, you can see how complicated the below code is. Lots of casting happening in the below code, right.
// Before the introduction of dynamic. Application excelApplication = new Application(); ((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name"; Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];
Now look at how simple the code becomes by using the dynamic keyword. No casting needed and during runtime type checking also happens.
// After the introduction of dynamic, the access to the Value property and // the conversion to Excel.Range are handled by the runtime COM binder. dynamic excelApp = new ApplicationO; excelApp.Cells[1, 1].Value = "Name"; Excel.Range range2010 = excelApp.Cells[1, 1];
Question 38:
What is the difference between Reflection and Dynamic?
Answer:
- Both reflection and dynamic are used when we want to operate on an object during runtime.
- Reflection is used to inspect metadata (data about data) of an object. It also has the ability to invoke members of an object on runtime.
- Dynamic is a keyword which was introduced in .NET 4.0. It evaluates object calls during runtime. So until the method calls are made compiler is least bothered if those methods / properties exist or not.
- Dynamic uses reflection internally. It caches the method calls made thus improving performance to a certain extent.
- Reflection can invoke both public and private members of an object while dynamic can only invoke public members.
Below is the detail comparison Table which shows in which scenario they are suited.
Reflection | Dynamic | |
Inspect (Meta-data) | Yes | No |
Invoke Public members | Yes | Yes |
Invoke Private members | Yes | No |
Caching | No | Yes |
Figure 2.7 shows visually what reflection can do and what dynamic keyword can do.
Question 39:
Explain the difference between early binding and late binding.
Answer:
Early binding or early bound means the target methods, properties and functions are detected and checked during compile-time. If the method / function or property does not existor has a data type issues then the compiler throws an exception during compile-time.
Late binding is opposite of early binding. Methods, properties and functions are detected during runtime rather than compile-time. So if the method, function or property does not exist during runtime application will throw an exception.
Note: In simple words everything is early binded until you are using reflection or dynamic keyword.
Question 40:
What is the difference between var and dynamic keyword?
Answer:
Note: Comparing VAR and Dynamic keyword is like comparing Apples and oranges. Many people confuse VAR with the variant datatype of VB6 and there’s where interviewer fries to confuse you. But there is absolute no connection of var C# keyword with variant of VB6.
var is early binded (statically checked) while dynamic is late binded (dynamically evaluated).
var keyword looks at your right hand side data and then during compile-time it decides the left hand side data type.In other words var keyword just saves you typing lot of things.
On the other hand dynamic keyword is for completely different purpose. Dynamic objects are evaluated during runtime. For instance in the below code the “Length” property exists or not is evaluated during runtime.
dynamic z = “Dynamic”; y = z. Length; // Is Length present or not checked during runtime
If for some reason you mistype the “Length” property to “length” (Small T) you would end up into a runtime exception as shown in the figure 2.9.
So in short sentence var does static check while dynamic evaluates and checks during runtime.
Question 41:
Explain term type safety and casting in C#.
Answer:
There are two types of languages one which is type safe and one which is not. Type safety means preventing type errors. Type error occurs when data type of one type is assigned to other type unknowingly and we get undesirable results. .
For instance JavaScript is a not a type safe language. In the below code “num” is a numeric variable and “str” is string. Javascript allows me to do “num + str”, now guess will it do arithmetic or concatenation.
Now the result of the below code is “55” but the important point is the confusion created what kind of operation it will do.
This is happening because JavaScript is not a type safe language. It allow to set one type of data to the other type without restrictions.
<script> var num =5; // numeric var str = "5"; // string var z = num + str; // arthimetic or concat???? alert(z); // displays "55" </script>
C# is a type safe language. It does not allow one data type to be assigned to other data type. The below code does not allow “+” operator on different data types.
But in certain scenarios we would like to convert the data type to achieve the given results that’s where we need to do conversion or casting. The next question talks about the same in detail.
Question 42:
Explain casting, implicit conversion and explicit conversion.
Answer:
Note: Some of interviewers term this conversion as casting and some just prefer to call it as conversion, at the end of the day they mean the same thing.
To understand implicit and explicit conversion of data types first let’s try to understand type casting concept. Typecasting is a mechanism where we convert one type of data to other type.
For example, below is simple code where we want to move integer (value without decimals) value to a double (value with decimals). When we try to move double data type to integer data typecasting occurs. Casting is also termed as conversion.
int i = 100; double d = 0; d = i; // casting
In the above example there is no loss of data. In other words when we moved 100 integer value to double we get the 100 value as it. This is termed as implicit conversion / casting.
Now consider the below code where we are trying to move a double to an integer. In this scenario in integer only 100 will be received and decimals will be removed. You can also see I need to explicitly specify that we need to convert into integer. This is termed as explicit conversion.
double d = 100.23; int i=0; i = (int) d; // this will have 100, 0.23 will truncated.
Question 43:
What are stack and heap?
Answer:
Stack and heap are memory types in an application. Stack memory stores data types like int, double, Boolean, etc., while heap stores data types like string and objects.
For instance when the below code runs, the first two variables, i.e., “i” and “y” are stored in a stack and the last variable “o” is stored in heap.
void MyFunction() { int i = 1; // This is stored in stack, int y = i; // This is stored in stack, object o = null; // This is stored in heap. } // after this end the stack variable memory space is reclaimed while // the heap memory is reclaimed later by garbage collector.
Question 44:
What are Value types and Reference types?
Answer:
Value types contain actual data while reference types contain pointers and the pointers point to the actual data.
Value types are stored on stack while reference types are stored on heap. Value types are your normal data types like int, bool, double and reference types are all objects.
Question 45:
What is concept of Boxing and Unboxing?
Answer:
When value type is moved to a reference type it’s called as boxing. The vice-versa is termed as unboxing.
Below is sample code of boxing and unboxing where integer data type is converted into object and then vice versa.
int i = 1; object obj = i; // boxing int j = (int) obj; // unboxing
Question 46:
How performance is affected due to boxing and unboxing?
Answer:
When boxing and unboxing happens the data needs to jump from stack memory to heap and vice- versa which is a bit of memory intensive process. As a good practice avoid boxing and unboxing whereever possible.
Question 47:
How can we avoid boxing and unboxing?
Answer:
First thing it’s very difficult to avoid boxing and unboxing. For instance most of the time you will moving data from Ul objects like textboxes, etc., to business objects and also vice versa which will demand boxing and unboxing. Below are some key points to remember:
- First thing is it really necessary to use boxing and unboxing. If it’s unavoidable like moving data from Ul text boxes to internal C# data types, then go for it.
- Try to see if you can use generics and avoid it.
Question 48:
If we have a class referencing value type, where is value type stored?
Answer:
The value type will be stored in a heap.
Question 49:
Are static variables stored on a heap or stack?
Answer:
Static variables and even their value types are stored in a heap.
Question 50:
How to prevent my .NET DLL to be decompiled?
Answer:
As per design, .NET embeds rich metadata inside the executable code using MSIL (Microsoft Intermediate Language). Anyone can easily decompile your DLL back using tools like ILDASM (owned by Microsoft) or Reflector for .NET which is a third party. Secondly, there are many third party tools, which make this decompiling process a click away. So anyone can easily look into your assembliesand reverse engineer them back into actual source code and understand some real good logic, which can make it easy to crack your application.
The process by which you can stop this reverse engineering is using “obfuscation”. It is a technique, which will foil the decompilers. Many third parties (XenoCode, Demeanor for .NET) provide .NET obfuscation solution. Microsoft includes one that is Dotfuscator Community Edition with Visual Studio.NET.
Note: We leave this as homework to reader’s compile, a DLL obfuscate it using “Dotfuscator Community Edition” which comes with Visual Studio.NET and try viewing the same using ILDASM.
Question 51:
What is the difference between Convert.ToString and .ToString () methods?
Answer:
To understand what the above question means see the code given.
int i =0; MessageBox.Show(i.ToString()); MessageBox.Show(Convert.ToString(i));
We can convert the integer “i” using “i .ToString () ” or “Convert.ToString” so what is the difference. The basic difference between them is “Convert” function which handles NULLs while ” i. ToString ()” does not do. It will throw a NULL referencing exception error. So as a good coding practice using “Convert” is always safe.
Question 52:
What is the difference between String and string?
Answer:
“String” is an alias (the same thing called with different names) of “string”. So technically both the below code statements will give the same output.
String s = "C# interview questions”;
or
string s = “C# interview questions";
In the same way there are aliases for other C# data type as shown below.
- object: Object
- string: String
- bool: Boolean
- byte: Byte
- sbyte: SByte
- short: Intl6
- ushort: uintl6
- int: Int32
- uint: UInt32
- long: Int64
- ulong: UInt64
- float: Single
- double: Double
- decimal: Decimal
- char: System.Char
Question 53:
So when both mean the same thing why are they different?
Answer:
When we talk about .NET there are two different aspects one there is .NET framework and the other there are languages (C#, VB.NET, etc.) which use that Framework as shown in Figure 2.11.
“System.String” i.e. “String” (capital “S”) is a .NET Framework data type while “string” is a C# data type.
Question 54:
So when to use “String” and “string”?
Answer:
First thing to avoid confusion use one of them consistently. But from best practices perspective when you do variable declaration it’s good to use “string” (small “s”) and when you are using it as a class name then “String” (capital “S”) is preferred.
In the below code a variable is declared in the left hand side using “string”. At the’right hand side a method is called so “String” is more sensible.
string s = String. ToUpperQ ;
Question 55:
How can we handle exceptions in .NET?
Answer:
Exceptions are handled by “System.Exception” base class. If you want to raise an error from source you need to create the Exception object with below code snippet.
throw new Exception (“Customer code cannot be more than 10’);
Once the exception is raised, and if you want to catch the same you need to use the try-catch block as shown below.
try { // This section will have the code which // which can throw exceptions. } catch(Exception e) { // Handle what you want to //do with the exception label.text = e.Message; }
Question 56:
How can I know from which source the exception occurred?
Answer:
“System. Exception. stackTrace” allows you to identify series of call which lead to this exception.
Question 57:
What if we do not catch the exception?
Answer:
If you do not catch the error, .NET Framework will handle the same and you will get a message box as shown in the Figure 2.13.
Question 58:
What are system level exceptions and application level exceptions?
Answer:
Exceptions that are thrown by .NET Framework are called as system exceptions. These errors are non-recoverable or fatal errors like ArgumentOutOfRangeException, IndexOut OfRangeException, StackOverflowException, etc.
Application exceptions are custom exceptions created for the application. Application exceptions are created by deriving from “ApplicationException” class as shown below. You can then create the object of the below exception, throw the same from the code and catch the same on the client side. .
public class MyOwnException: ApplicationException { private string messageDetails = String.Empty; public DateTime ErrorTimeStamp {get; set;} public string CauseOfError {get; set;} public MyOwnException(){} public MyOwnException(string message, string cause, DateTime time) { messageDetails = message; CauseOfError = cause; ErrorTimeStamp = time; } // Override the Exception.Message property. public override string Message { get { return string.Format("This is my own error message"); } } }
Question 59:
Can two catch blocks be executed?
Answer:
No, once the proper catch section is executed the control goes to the ‘finally’ block. So there is no chance by which multiple catch block will ‘execute’.
Question 60:
What are different types of collections in .NET?
Answer:
There are five important collections in .NET Arrays, Lists, Hashtable, stacks and queues.
Question 61:
What is the difference between ArrayList and List?
Answer:
- Arrays are fixed in size while ArrayList is resizable.
- Arrays are strongly typed, in other words when you create an array it can store only one data type data. ArrayList can store any datatype.
Question 62:
Is ArrayList faster or Arrays?
Answer:
ArrayList takes any data type which leads to boxing and unboxing. As arrays are strongly typed they do not do boxing and unboxing. So arrays are faster as compared to ArrayList.
// Array definition int [ ] str = new int[10]; // Arraylist definition ArrayList MyList = new ArrayListO;
Question 63:
What are hashtable collections?
Answer:
In ArrayList or array if we have to access any data we need to use the internal index id generated by the ArrayList collection. For instance the below code snippet shows how the internal id is used to fetch data from ArrayList.
In actual scenarios we hardly remember internal id’s generated by collection we would like to fetch the data by using some application defined key. There’s where hashtable comes into picture.
string str = MyList[ 1 ]. ToStringQ;
Hashtable helps to locate data using keys as shown below. When we add data to hashtable it also has a provision where we can add key with the data. This key will help us to fetch data later using key rather than using internal index id’s generated by collections.
objHashtable.Add(“p001”, “MyData’);
This key is converted in to numeric hash value which is mapped with the key for quick lookup.
Question 64:
What are Queues and stack collection?
Answer:
Queues are collection which helps us to add object and retrieve them in the manner they were added. In other word queues helps us to achieve the First In First Out (FIFO) collection behavior.
Stack collection helps us to achieve Frst In Last Out (FILO) behavior.
Question 65:
Can you explain generics in .NET?
Answer:
Generics help to separate logic and data type to increase reusability. In other words you can create a class whose data type can be defined on runtime.
For instance below is a simple class “Classl” with a “Compareme” function created using generics. You can see how the unknown data type is put in greater than and less than symbol. Even the Compareme method has the unknown data type attached.
public class Classl<UNNKOWDATATYPE> { public bool Compareme(UNNKOWDATATYPE vl, UNNKOWDATATYPE v2) { if (vl.Equals(v2)) { return true; } else { return false; } } }
During runtime you can define the datatype as shown in the below code snippet.
Class1<int> obj = new Class1<int> () ; bool b = obj.Compareme(1, 2) ; // This compares numeric Class1<string> obj1 = new Class1<string>(); bool b1 = obj1.Compareme("shiv", "shiv") ; // This does string comparison
Question 66:
Explain generic constraints and when should we use them.
Answer:
Generic’s helps to decouple logic from the data type. But many times some logics are very specific to specific data types.
public class CompareNumeric<UNNKOWDATATYPE> { public bool Compareme(UNNKOWDATATYPE v1, UNNKOWDATATYPE v2) { if (v1>v2) {return true; } else {return false;} } }
For example above is a simple generic class which does comparison if one number is greater than other number. Now the greater and less than comparison is very specific to numeric data types. These kind of comparison’s cannot be done on non-numeric types like string.
So if some uses the classes with ” int” type it is perfectly valid.
CompareNumeric<int> obj = new CompareNumeric<int>(); bool boolgreater = obj.Compare(10, 20);
If someone uses it with “double” data type again perfectly valid.
CompareNumeric<double> obj = new CompareNumeric<double>(); bool boolgreater = obj.Compare(100.23, 20.45);
But using string data type with this logic will lead undesirable results. So we would like to restrict or put a constraint on what kind of types can be attached to a generic class this is achieved by using “generic constraints”.
CompareNumeric<string> obj = new CompareNumeric<string>(); bool boolgreater = obj. Compare(“interview’’, “interviewer’);
Generic type can be restricted by specifying data type using the “where” keyword after the generic class as shown in the code given below. Now if any client tries to attach “string” data type with the below class it will not allow, thus avoiding undesirable results.
public class CompareNumeric<UNNKOWDATATYPE> where UNNKOWDATATYPE: int, double { }
Question 67:
Can you explain the concept of generic collection?
Answer:
Arraylist, Stack and Queues provide collections which are not type safe. This leads {wo problems first it is not type safe, and second it leads to boxing and unboxing. .
By using generics we can have type safety, and also we can avoid boxing and unboxing. Below is a simple code snippet which shows a strong typed list of type integer and string.
List<int> obj; obj.add(1); // you can only add integers to this list List<string> obj; obj.add("shiv"); // you can only add string to this list
Question 68:
What is the difference between dictionary and hashtabie?
Answer:
Dictionary collection is a generic collection equivalent for hashtabie. Hashtabie allows you to add key and value of any type (i.e., objects). This leads to two problems one is boxing and unboxing issues and second it’s not strongly typed.
// Creates a strongly typed dictionary with integer key and value // pair Dictionary<int, int> obj = new Dictionary<int, int>(); //We can only add integer value and key to the dictionary collection Obj.Add(123, 550);
Question 69:
What are the generic equivalent for ArrayList, stack, queues and hashtabie?
Answer:
Below are the listed generic equivalents for each of them:
- Arraylist generic equivalent is List<int>.
- Stack generic equivalent is stack<int>.
- Queue generic equivalent is Queue<int>.
- Hashtabie generic equivalent is Dictionarycint, int>.
Question 70:
What is the use of lEnumerable, (Collection, Hist and (Dictionary?
Answer:
The above four entities are nothing but interfaces implemented by collections as shown in Figure 2.14:
- lEnumerable: All collection classes use this interface and it helps to iterate through all the collection elements.
- Collection: This interface has the count property and it is implemented by all collection elements.
- IList: This interface allows random access, insertion and deletion in to the collection. It is implemented by arraylist.
- IDictionary: This interface is implemented by hashtabie and dictionary.
Question 71:
Differentiate between lEnumerable and IQueryable.
Answer:
The first important point to remember is “IQueryable” interface is inherited from “lEnumerable”, so whatever “lEnumerable” can do, “IQueryable” can also do.
There are many differences but let us discuss about the one big difference. “IQueryable” interface is useful when your collection is loaded using LINQ or Entity Framework, and you want to apply filter on the collection.
Consider the code given below which uses “lEnumerable” with entity framework. It is using a “Where” filter to get records whose “Empid” is “2”.
EmpEntities ent = new EmpEntities(); IEnumerable<Employee> emp = ent.Employees; IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
The filter is executed on the client side where the “iEnumerable” interface is coded. In other words all the data is fetched from the database and then at the client its scans and gets the record with “Empid” is “2” as shown in Figure 2.16.
But now see the below code we have changed “IEnumerable” to “iQueryable”.
EmpEntities ent = new EmpEntities(); IQueryable<Employee> emp = ent.Employees; IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
In this case the filter is applied on the database using the “SQL” query. So the client sends a request and on the server-side a selected query is filtered on the database and only necessary data is returned ; as shown in Figure 2.17.
So the difference between “IQueryable” and “IEnumerable” is the process how the filter logic is executed. One executes on the client-side and the other executes on the database.
So if you working with only in-memory data collection “IEnumerable” is a good choice but if you want to query data collection which is connected with database “IQueryable” is a better choice as it reduces network traffic and uses the power of SQL (Structured Query Language).
Question 72:
What is Code Access Security (CAS)?
Answer:
It is a four step process as shown in Figure 2.18. These steps are as follows:
- First evidence is gathered about the assembly. In other words from where did this assembly come, who is the publisher, etc.
- Depending on evidences the assembly is assigned to a code group. In other words what rights does the assembly depending on the evidence gathered.
- Depending on code group security rights are allocated.
- Using the security rights the assembly is run within those rights.
Question 73:
Is CAS supported in .NET 4.0?
Answer:
CAS is deprecated in .NET 4.0 and two major changes are brought in:
- Permission granting is no more the work of CAS; it’s now the work of the hosting model. In other words CAS is disabled in .NET 4.0 by default. The host will decide what rights to be given to the .NET assembly.
- A new security model, i.e., security transparent model is introduced. The security transparent model puts code in to separate compartments/boxes as per the risk associated. If you know a code can do something wrong you can compartmentalize the code as ‘Security transparent’ and if you have a code which you trust you can box them into ‘Security critical’.
Question 74:
What is sandboxing?
Answer:
If you have want to execute an untrusted third party DLL (Dynamic Link Library), you can create your own ‘appdomain’ and assign permission sets so that your third party DLL runs under a control environment.
Question 75:
How can we create a Windows service using .NET?
Answer:
Windows Services are long-running processes that run at the background. It has the ability to start automatically when the computer boots and also can be manually paused, stopped or even restarted.
Following are the steps to create a service:
Create a project of type “Windows Service”.
If you see, the class created it is automatically inherited from “System.Servic’eProcess. ServiceBase”.
You can override the following events provided by service and write your custom code. All the three main events can be used that is Start, Stop and Continue.
protected override void OnStart(string[ ] args) { } protected override void OnStopO { } protected override void OnContinue() { }
Now to install the service you need to do run the lnstallUtil.exe.
InstallUtil <Project Path>\BIN\MyNewService.exe
Question 76:
What is serialization and deserialization in .NET?
Answer:
Serialization is a process where we can convert an object state in to stream of bytes as shown in Figure 2.20. This stream can then be persisted in a file, database, or sent over a network, etc. Deserialization is just vice-versa of serialization where we convert stream of bytes back to the original object.
Below is a simple code of howto serialize and deserialize an object.
Let’s first start with serialization.
Step 1: Create the object and put some values
// Serialization Customer obj = new Customer!) ; // Create object obj.CustomerCode = 123; // Set some values
Step 2: Create the file where the object is saved.
using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; IFormatter i = new BinaryFormatter(); // Use the binary formatter Stream stream = new Fi1eStrearn("MyFi1e.txt" , FileMode.Create, FileAccess.Write, FileShare.None); // Give file name
Step 3: Use Serialize method to save it to hard disk
i.Serialize(stream, o); // write it to the file stream.Close(); // Close the stream
Let’s also see a simple example of deserialization.
Step 1: Read the file
// Deserialization IFormatter formatter = new Binary-Formatter () ; // Use binary formatter Stream stream = new FileStream("MyFile.txt", FileMode.Open, FileAccess.Read, FileShare.Read); // read the file
Step 2: Recreate it back to the original object.
Customer obj = (Customer)formatter.Deserialize(stream); // take data back to object stream.Close(); // close the stream
If you want to save as XML or any other content type use the appropriate formatter.
Question 77:
Can you mention some scenarios where we can use serialization?
Answer:
Below are some scenarios where serialization is needed:
- Passing .NET objects across network. For example, .NET remoting, Web services or WCF services use serialization internally.
- Copy and paste .NET objects on the Clipboard.
- Saving old state of the object and reverting back when needed. For example, when the user hits the Cancel button you would like to revert back to the previous state.
Question 78:
When should we use binary serialization as compared to XML serialization?
Answer:
- Binary is smaller in size, so faster to send across network and also faster to process.
- XML is more verbose, but easy to understand and human readable. But due to the XML structure it is complex to parse and can impact on performance.
Note: Many people answer that XML serialization should be used when you have different platforms and binary serialization should be used when you have same platforms. But this answer is actually not right as we have lot of binary serialization methodologies like ASN (Abstract Syntax Notation), protbuf which are cross platform and widely accepted. So the important difference is that one is XML which readable by eyes and the binary is not.
Question 79:
What is regular expression?
Answer:
Regular expression is a pattern matching technique. Most of the data follow patterns. Some examples of common data patterns are shown in the Table
E-mail Address | [email protected] abc@[email protected] |
Email address data starts with some characters followed by “@” and then “.” a and finally the domain extension. |
Phone number | 901-9090-909023 909-999-1202920 |
Phone number data starts with an international code followed by region code and then the phone number. |
By using regular expression you can represent these data patterns and utilize the same for validations and manipulation of data.
In order to use regular expression we need to create the object of “Regex” class and pass the pattern to Regex. For example, the below pattern represents data pattern of 10 character length which can be any small characters from a to z.
Regex obj = new Regex(“[a-z]{10}’);
Once you have specified the pattern as described in the previous step you can then use the “isMatch” function to check if the data matches with the pattern.
if(obj.IsMatch("shivkoirala")) { // proper data } else { // improper data }
Note: In some rare cases we have seen interviewers ask to write down Regex patterns. So we would suggest to see the video “Explain Regex.”provided in the DVD which will help you to write down any Regex pattern easily.
Question 80:
What is timeout support in Regex (regular expression)?
Answer:
This is a new feature of .NET 4.5. Some of the regular expressions are very complex and they can take lot of time to be evaluated.
For instance below is a simple regular expression.
var regEx = new Regex(@”^(\d+)+$”, RegexOptions.Singleline);
If someone inputs a huge number as shown in the below code snippet. It will take more than a minute to resolve the expression leading to a lot of loads on the application. So we would like to give a time out on the expression. So if the validation takes more than a specific interval we would like the application to give up and move ahead.
var match = regEx.Match(“123453109839109283090492309480329489812093809x’);
In .NET 4.5 we can now provide the timeout value as parameter on the constructor. For instance in the below code we have provided 2 seconds timeout on the Regex (regular expression). So if it exceeds more than 2 second “RegexMatchTimeOutException” will occur,
try { var regEx = new Regex(A(\d+)+$", RegexOptions.Singleline, TimeSpan.FromSeconds(2)); var match = regEx.Match ("123453109839109283090492309480329489812093809x"); } catch (RegexMatchTimeOutException ex) { Console.WriteLine("Regex Timeout"); }
Question 81:
Can you explain the concept of “Short Circuiting”?
Answer:
Short circuiting occurs when you do logical operations like ‘AND’ and ‘OR’.
“When we use short circuit operators only necessary evaluation is done rather than full evaluation.”
Let us try to understand the above sentence with a proper example. Consider a simple “AND” condition code as shown below. Please note we have only one operator in the below code.
if(Condition1 & Condition2) { }
In the above case “Condition?1 will be evaluated even if “Condition1” is “false”. Now if you think logically, it does not make sense to evaluate “Condition 2”, if “Condition 1” is false. It is a AND condition right? So if the first condition is false it means the complete AND condition is false and it makes no sense to evaluate “Condition2”.
There’s where we can use short circuit operator For the below code “Condition 2” will be evaluated only when “Condition 1 ” is true.
if(Condition1 && Condition2) { }
The same applies for “OR” operation. For the below code (please note its only single pipe (” |”).) “Condition2” will be evaluated even if “Conditionl” is “true”. If you think logically we do not need to evaluate “Condition?’ if “Conditionl” is “true”.
if(Condition1 | Condition2) { }
So if we change the same to double pipe (” | |”), i.e., implement short circuit operators as shown in the below code, “Condition2” will be evaluated only if “Conditionl” is “false”.
if(Condition1 || Condition2) { }
Question 82:
What is the difference between “Typeof” and “GetType”?
Answer:
Both “TypeOf” and “GetType” help you to get the type. The difference is from where the information is extracted. “Typeof” gets the type from a class while “GetType” gets type from an object.
Question 83:
Will the following C# code compile?
Answer:
double dbl = 109.22; int i = dbl;
No, the above code will give an error. Double size is larger than “int” so an implicit conversion will not take place. For that we need to do explicit conversion. In the below code we have done an explicit conversion.
double dbl = 109.22; int i =(int) dbl; // this is explicit conversion /casting
Also note after explicit conversion we will have data loss. In variable “i” we will get “109” value, the decimal values will be eliminated.
Question 84:
Explain the use of IComparable in C#.
Answer:
“IComparable” interface helps to implement custom sorting for collections in C#. Let us try to understand the same concept with a simple C# example. For instance let’s say you have a list collection of people names as shown in the below code.
List<string> Peoples = new List<string>(); Peoples.Add("Shiv"); Peoples.Add("Raju"); Peoples.Add("Sukesh") ; Peoples.Add("Ajay"); foreach (string str in Peoples) { Console.WriteLine(str); }
Now if you run the above program you will see that we have not applied sorting on the collection. It displays data as they were inserted.
Shiv Raju Sukesh Ajay
But now if you call “Peoples. Sort ()” method on the collection you will get the following sorted output on the “name” value in ascending order.
Ajay Raju Shiv Sukesh
But now let’s say that we need the person’s age also to be added in the list with the person name value. So logically you will create a “Person” class with “Name” and “Age” properties as shown in the code below.
class Person { private string _Name; public string Name { get { return _Name; } set { _Name = value; } } private int _Age; public int Age { get { return _Age; } set { _Age = value; } } }
Once you create the class you would create an object of the Person class and add it to the list collection as shown in the below code snippet.
class Program { static void Main(string[] args) { List<Person> Peoples = new List<Person>(); Peoples.Add(Createperson("Shiv", 20)); Peoples.Add(Createperson("Raju", 20)); Peoples.Add(Createperson("Sukesh", 30)); Peoples.Add(Createperson("Ajay", 40)) ; Peoples.Sort(); foreach (Person obj in Peoples) { Console.WriteLine(obj.Name + " " + obj.Age); } } static Person Createperson(string Name, int Age) { Person obj = new Person(); obj.Name = Name; obj.Age = Age; return obj; } }
But if you try to call the “Sort” method in the given List, there would be confusion like sort() method works on values given for “Name” or “Age”.
If you run the application it will throw up the below exception text. The exception text needs specific direction on how the sorting should work. This direction can be provided by using “icomparable” interface as shown in Figure 2.21.
Unhandled Exception: System.InvalidOperationException: Failed to compare two elements in the array. —> System. ArgumentException: At least one object must implement IComparable.
So in order to show a proper direction for the sort logic we need to implement ” icomparable” interface as shown in the code below. The logic of “Sort” method needs to be defined in the “CompareTo” method.
class Person: IComparable<Person> { private string _Name; public string Name { get { return _Name; } set { _Name = value; } } private int _Age; public int Age { get { return _Age; } set { _Age = value; } } public int CompareTo(Person other) { if (other.Age == this.Age) { return this.Name.CompareTo(other.Name); } else { return other.Age.CompareTo(this.Age); } } }
You can see in the “CompareTo” method that we have applied the logic saying if the “Age” value is same then sort by using the “Name” value else use “Age” value. If you run the application you would get the following output. You can see for “40” and “30” have been sorted on the basis of “Age” but for the remaining people the age is same so “Name” values have been sorted.
Loki 40 Sukesh 30 A jay 20 Madan 20 Raju 20 Shiv 20
So “icomparable” interface customized sorting logic on the given list.
Question 85:
What is difference between Icomparable and IComparer?
Answer:
Pre-requisite: Please read “Explain the use of Icomparable in C#.”, before reading this answer.
“icomparable” interface helps you to implement a default sort implementation for the collection. But what if we want to sort using multiple criteria. For those instances “IComparable” has a limitation.
For example, if we want to sort the list by “Name” under some situation or sort by “Age” under some other situation we need to implement “IComparer” interface.
So the first step is to create different classes for each sort criteria. These classes will implement “IComparer” interface and will have sorting logic defined in the “Compare” method. You can see we have two different classes defined “CompareByName” and “CompareByAge”. One compares on the basis of “Name” and the other on the basis of “Name”.
class CompareByName: IComparer<Person> { public int Compare(Person x, Person y) { return string.Compare(x.Name, y.Name); } } class CompareByAge: IComparer<Person> { public int Compare(Person x, Person y) { if (x.Age > y.Age) return 1; if (x.Age < y.Age) return -1; return 0; } }
If you see the logic for “CompareByName” it is simple. It uses the string comparison to evaluate the “Name” value sorting. But when we talk about numeric comparison there are three possible outputs Greater than, Less than or Equal. So if you see “CompareByAge” class it returns three values 1 (Greater than), -1 (Less than) and 0 (for Equal to).
Now that we have created the separate logics we can now invoke the “Peoples” list by passing the class object. So for example if we want to sort by name, you will use the below code snippet.
Peoples. Sort(new CompareByNameQ);
The output of the above code is nothing but alphabetically sorted data.
Ajay 20 Loki 40 Madan 20 Raju 20 Shiv 20 Sukesh 30
If you invoke the Sort () method of the list by using the Age logic it will throw an output sorted on Age value.
Peoples.Sort(new CompareByAgeQ);
Ajay 20 Raju 20 Shiv 20 Madan 20 Sukesh 30 Loki 40
So the difference is really default internal implementation or customizable external implementation. When we use “icomparable” we can have only one default sorting logic and that logic goes inside the collection itself. For “icomparator” the logic is outside the collection, in other words more extensible and the collection is not disturbed as shown in Figure 2.22.
Question 86:
Can you explain Lazy Loading?
Answer:
Lazy loading is a concept where we delay the loading of the object unit the point where we need it. Putting in simple words on demand object loading rather than loading the objects unnecessarily.
For example, consider the below example where we have a simple “Customer” class and this “Customer” class has many “Order” objects inside it. Have a close look at the constructor of the “Customer” class. When the “Customer” object is created it also loads the “Order” object at that moment. So even if we need or do not need the address object, it is still loaded.
But how about just loading the “Customer” object initially and then on demand basis load the “Order” object,
public class Customer { private List<Order> _Orders= null; ... ... public Customer() { _CustomerName = "Shiv"; _Orders = LoadOrders() ; // Loads the address object even though //not needed } private List<Order> LoadOrders() { List<Order> temp = new List<Order>(); Order o = new Order(); o.OrderNumber = "ordlOOl"; temp.Add(o); o = new Order(); o.OrderNumber = "ordl002"; temp.Add(o); return temp; } }
So let’s consider you have client code which consumes the “Customer” class as shown below. So when the “Customer” object is created no “Order” objects should be loaded at that moment. But as soon as the “foreach” loop runs you would like to load the “Order” object at that point (on demand object loading).
Customer o = new Customer( ); // Address object not loaded Console.WriteLine(o.CustomerName); foreach (Order ol in o.Orders) // Load address object only at this moment { Console.WriteLine(ol.OrderNumber); }
Question 87:
So how do we implement “Lazy Loading”?
Answer:
So for the above example if we want to implement lazy loading we will need to make the following changes:
- Remove the “Order” object loading from the constructor.
- In the “Order” get property, load the “Order” object only if it is not loaded.
public class Customer { private List<Order> _Orders= null; ... ... public Customer() { _CustomerName = "Shiv"; } public List<Order> Orders { get { if (_Orders == null) { _Orders = LoadOrders(); } return _Orders; } } }
Now if you run the client code and halt your debugger just before the ” foreach” loop runs over the “Order” object, you can see the “Order” object is null (i.e., not loaded) as shown in Figure 2.23. But as soon as the “ForEach” loop runs over the “Order” object, it creates the “Order” object collection.
Question 88:
Are there any readymade objects in .NET by which we can implement lazy loading?
Answer:
In .NET we have “Lazy<T>” class which provides automatic support for lazy loading. So let’s say if you want to implement “Lazyo” in the above code we need to implement two steps for the same:
Create the object of orders using the “Lazy” generic class.
private Lazy<List<Order» _Orders= null;
Attach this Lazyo object with the method which will help us load the order’s data.
_Orders = new Lazy<List<Order»(() => LoadOrdersQ);
Now as soon as any client makes a call to the ”_Orders” object, it will call the “LoadOrders” method to load the data.
You will get the “List<Orders>” data in the “Value” property.
public List<Order> Orders { get { return _Orders.Value; } }
Below goes the full code for the same.
public class Customer { private Lazy<List<Order>> _Orders= null; public List<Order> Orders { get { return _Orders.Value; } } public Customer() { // Makes a database trip _CustomerName = "Shiv"; _Orders = new Lazy<List<Order>>(() => LoadOrders()); } }
Question 89:
What are the advantages/disadvantages of lazy loading?
Answer:
Below are the advantages of lazy loading:
- Minimizes start up time of the application.
- Application consumes less memory because of on-demand loading.
- Unnecessary database SQL execution is avoided.
The disadvantage is that the code becomes complicated. As we need to do checks if the loading is needed or not. So must be there is a slight decrease in performance.
But the advantages are far more than the disadvantages.
FYI: The opposite of Lazy loading is Eager loading. So in eager loading we load the all the objects in memory as soon as the object is created.
Question 90:
What is the difference between “is” and “as” keyword?
Answer:
“is” keyword is useful to check if objects are compatible with a type. For instance in the below code we are checking if “ocust” object is a type of “Customer” class.
object ocust = new Customer(); if (ocust is Customer) {
“as” keyword helps to do conversion from one type to other type. For instance in the below code we are converting object to a string data type. If the “as” keyword is not able to typecast it returns NULL.
object o = “interview”; string str = o as string;
Question 91:
What is the use of “Yield” keyword?
Answer:
“Yield helps you to provide 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.
Scenario 1: Customized iteration through a collection
Let’s try to understand what customized iteration means with an example. Consider the below code.
Let say we have a simple list called as “MyList” which has collection of five consecutive numeric values 1,2, 3, 4 and 5 as shown in Figure 2.24. This list is browsed/iterated from console application from within static void Main() method.
For now let’s visualize the “Main ()” method as a caller. So the caller, i.e., “Main ()” method calls the list and displays the items inside it. Simple…til! now ;-).
static List<int> MyList = new List<int>(); static void FillValues() { MyList.Add(1); MyList.Add(2 ) ; MyList.Add(3) ; MyList.Add(4); MyList.Add(5); } static void Main(string[ ] args) // Caller { FillValues(); // Fills the list with 5 values foreach (int i in MyList) // Browses through the list { Console.WriteLine(i); } Console.ReadLine(); }
Now let me complicate this situation lets say the caller only wants values greater than “3” from the collection. So the obvious thing as a C# developer we will create a function as shown below. This function will be temporary collection of given values. In this temporary collection we will first add values which are greater than “3” and return the same to the caller. The caller can then iterate through this collection.
static IEnumerable<int> FilterWithoutYield() { List<int> temp = new List<int>(); foreach (int i in MyList) { if (i > 3) { temp.Add(i); } } return temp; }
Now the above approach is fine but it would be great if we would get rid of the collection, so that our code becomes simple as shown in Figure 2.25. This where “yield” keyword comes to help. Below is a simple code how we have used yield.
“yield” keyword will return back the control to the caller, the caller will do its work and re-enter the function from where it had left and continue iteration from that point onwards. In other words “yield” keyword moves control of the program to and from between caller and the collection.
static IEnumerable<int> FilterWithYield() { foreach (int i in MyList) { if (i > 3) yield return i; } }
So for the above code, following are steps how the control will flow between caller and collection. You can also see the pictorial representation in the Figure 2.26.
- Step 1: Caller calls the function to iterate for number’s greater than 3,
- Step 2: Inside the function the for loop runs from 1 to 2, from 2 to 3 until it encounters value greater than “3” i.e. “4”. As soon as the condition of value greater than 3 is met the “yield” keyword sends this data back to the caller.
- Step 3: Caller displays the value on the console and re-enters the function for more data. This time when it reenters, it does not start from first. It remembers the state and starts from “5”. The iteration continues further as usual.
Scenario 2: Stateful iteration
Now let us add more complications to the above scenario. Let’s say we want to display running total of the above collection. What do I mean?.
In other words we will browse from 1 to 5 and as we browse we would keep adding the total in variable. So we start with “1” the running total is “1”, we move to value “2” the running total is previous value “1 ” plus current value “2”, i.e., “3” and so on.
Figure 2.27 shows the pictorial representation of the running total looks like.
In other words we would like to iterate through the collection and as we iterate would like to maintain running total state and return the value to the caller (i.e., console application). So the function now becomes something as shown below. The “runningtotal” variable will have the old value every time the caller re-enters the function.
static IEnumerable<int> RunningTotal() { int runningtotal=0; int index=0; foreach(int i in MyList) { index = index + 1; if(index==l) { runningtotal = i; } else { runningtotal = i + runningtotal; } yield return (runningtotal); } }
Following is the caller code.
foreach (int i in RunningTotal()) { Console.WriteLine(i); } Console.ReadLine();
The output of the above program is shown in Figure 2.28.
Question 92:
What is the difference between “==” and .Equais()?
Answer:
When we create any object there are two parts to the object one is the content and the other is reference to that content as shown in Figure 2.29.
So for example if you create an object as shown in below code:
- “.NET Interview questions” is the content.
- “o” is the reference to that content.
object o = “.NET Interview questions”;
“= = ” compares if the object references are same while ”. Equals () ” compares if the contents are same as shown in Figure 2.31.
So if you run the below code both “==” and “.Equals () ” return true because content as well as references are same as shown in Figure 2.30.
object o = ".NET Interview questions"; object ol = o; Console.WriteLine(o == ol); Console.WriteLine(o.Equals(ol)); Console.ReadLine();
True
True
Now consider the below code where we have same content but they point towards different instances. So if you run the below code “==” will return false and “.EqualsO” will return true.
object o = ".NET Interview questions"; object o1 = new string(".NET Interview questionsToCharArray()); Console.WriteLine(o == ol) ; Console.WriteLine(o.Equals(ol)); Console.ReadLine();
False
True
When you are using string data type it always does content comparison. In other words you either use “. Equals ()” or “==” it always does content comparison.
Question 93:
What’s the difference between catch with parameter and catch without parameter?
Answer:
First let’s try to understand this question:
catch(Exception e) { .. } vs Catch { .. }
For this interview question many people answer, “Second one will cause compile error”. But both the codes will work properly. Actually from .NET 2.0 there is no difference. But in the initial versions of .NET, i.e., prior 2.0 some of the exceptions thrown by some COM components did not translate to “Exception” compatible object.
From .NET 2.0 both code will execute properly and there is no difference between them internally. Both catches will handle all kind of exceptions.
After 2.0 a catch which does have any code written in it gives a warning as shown in Figure 2.23. So many developers mark this as a difference.
But you can always overcome this issue by not putting a variable as shown in the code below.
catch (Exception) { }
Question 94:
What are attributes and why do we need it?
Answer:
“Attribute is nothing but a piece uf infer,- ration”.
This information can be attached to your method, class, namespace, assembly, etc. Attributes are part of your code this makes developers life easier as it can see the information right upfront in the code while it is calling the method or accessing the class and take actions accordingly.
For instance below is a simple class where “Methodl” is decorated by the “Obsolete” attribute. Attributes are defined by using the ” [ ]” symbol. So when developers starting coding in this class they are alerted that “Methodl” is obsolete and code should be now written in “NewMethodl ”.
public class Class1 { [Obsolete] public void Methodl() { } public void NewMethodl() { } }
In the same way if somebody is trying to create object of “Classl” it gets an alert in the tooltip as shown in the below code snippet that “Methodl” is obsolete and it should use “NewMethodl” as shown in Figure 2.33.
So in short Attributes are nothing small piece of information which is embedded declaratively in the code itself which developers can see
In case you want to show some message to the developers you can pass the message in the “Obsolete” attribute as shown in the below code snippet.
"Obsolete("Please use NewMethod1")] public void Methodl() { }
If you want to be bit strict and do not developers to use that method, you can pass “true” to the “Obsolete” attribute as shown in the below code.
"Obsolete("Please use NewMethod1", true)] public void Method1() { }
If you want to be bit strict and do not developers to use that method, you can pass “true” to the “Obsolete” attribute as shown in the below code.
"Obsolete("Please use NewMethod1", true)] public void Methodl() { }
Now in case developers try to make a call to “Methodl” they will get error and not just a simple warning.
Question 95:
How can we create custom Attributes?
Answer:
The “Obsolete” attribute which we discussed at the top is a readymade attribute. To create a custom attributes you need to inherit from the Attribute class. Below is a simple “HelpAttribute” which has a “HelpText” property.
class HelpAttribute: Attribute { public string HelpText { get; set; } }
“HelpAttribute” is applied to the “Customer” as shown in the code below. Now developers who see this class, see the information right in the front of their eyes.
[Help(HelpText="This is a class")] class Customer { private string _CustomerCode; [Help(HelpText = "This is a property")] public string CustomerCode { get { return __CustomerCode; } set { _CustomerCode = value; } } [Help(HelpText = "This is a method")] public void Add() { } }
Question 96:
How can we mark a method as deprecated?
Answer:
Refer the previous answer.
Question 97:
What is the difference between Build Solution, Rebuild Solution and Clean Solution menus?
Answer:
Build solution menu: This will perform an incremental build. In other words it will only build code files which have changed. If they have not changed those files will not touched.
Rebuild solution menu: This will delete all current compiled files (i.e., exe and dll’s) and will build everything from scratch, irrespective if there is code change in the file or not.
Clean solution menu: This menu will delete all compiled files (i.e., EXE’s and DLL’s) from “bin” I “obj” directory.
Now if you read the above three points I have discussed you can conclude that:
Rebuild = Clean + Build
So the next question would be If you do a “Rebuild” and if you do “Clean” + “Build”, what is the difference?.
The difference is the way the build and clean sequence happens for every project. Let’s say if your solution has two projects “Projl” and “Proj2”. If you do a rebuild it will take “Projl”, clean (delete) the compiled files for “Projl” and build it. After that it will take the second project “Proj2”, clean compiled files for “Proj2” and compile “Proj2”.
But if you do a “Clean” and “Build”. It will first delete all compiled files for “Projl” and “Proj2” and then it will build “Projl” first followed by “Proj2”.
Below image explains the same in a more visual format.
Question 98:
What is the difference between i++ and ++i?
Answer:
i++: In this scenario first the value is assigned and then increment happens. In the below code snippet first the value of “i” is assigned to ” j” and then “i” is incremented
++i: In this scenario first the increment is done and then value is assigned. In the below code snippet value of ” j ” is 2 and value of “i” is also “2”.
If you visualize in a pictorial manner below is how it looks like. So i + + is a postfix, it first assigns and then increments. While ++i is a prefix, it first increments and then assigns the value.
Below are some sample code where postfix and prefix fit in.
while (i < 5) //evaluates conditional statement { //some logic ++i; //increments i } while (i++ < 5) //evaluates conditional statement with i value before increment { //some logic } int i = 0; int[] MyArray = new int[2]; MyArray[i++] = 1234; //sets array at index 0 to '1234' and i is incremented MyArray[i] = 5678; //sets array at index 1 to '5678' int temp = MyArrayf—i]; //temp is 1234
Question 99:
When should we use “??” (NULL Coalescing operator)?
Answer:
“??” is a null coalescing operator. If you see the English meaning of coalescing it says “consolidate together”. Coalescing operator returns the first non-null value from a chain. For example, below is a simple coalescing code which chains four strings.
So if “str1” is null it will try “str2”, if “str2” is null it will try “str3” and so on until it finds a string with a non-null value.
string final -str1?? str2?? str3?? str4;
Question 100:
Explain need of NULLABLE types.
Answer:
It is difficult to assign null directly for value types like int, bool, double, etc. By using nullable types you can set value types as null. To create a nullable type we need to put ” ?” before the data type as shown in the below code.
int? num1 = null;
Question 101:
In what scenario’s we will use NULLABLE types?
Answer:
The biggest user of nullable types is when you are reading values from database. Database is one place where there is high possibility of column having null’s. So when we want to read those values into value types nullable types makes it easy as shown in the below code.
while (oreader.Read()) { int? salary = oreader["Salary"] as int? ; }
Question 102:
What is the benefit of coalescing?
Answer:
You do not need to write long if condition as shown below.
if (strl != null) { final = strl; } else if (str2 != null) { final = str2; } else { if (str3 != null) { final = str3; } else { if (str4 != null) { final = str4; } } } }