Tag Archives: C#

Table Value Parameters in SQL Server 2008 and .NET (C#)

Problem

We recently upgraded our database to SQL Server 2008 and I want to update our data access C# code to use Table Value Parameters with our stored procedures. In a previous tip I saw that Table Value Parameters were used with a Data Warehousing example. Can you show me how to implement Table Value Parameters with my .NET Application to insert multiple records using one round-trip?

Solution

Table Value Parameters is a new feature for developers in SQL Server 2008. It allows you to pass read-only table variables into a stored procedure. In the past I have used a comma delimited string or XML to simulate this purpose. I would have to parse out the string into a temp table similar to this example.

Once you have the table parameter passed into the stored procedure you can leverage the Table Value Parameter just like any other table except you cannot modify the parameter as it’s read-only. Below we will apply a common example to bulk insert data using one round trip.


Create table and table type

The following is a sample table that we will use in this example to insert items.

CREATE TABLE [dbo].[Items](
 [ItemID] [int] NOT NULL,
 [Name] [nvarchar](50) NULL,
 CONSTRAINT [PK_Items] PRIMARY KEY CLUSTERED 
(
 [ItemID] ASC
)) ON [PRIMARY]

In order to use table value parameters you have to create a table type. The table type is used to describe the structure of the table value parameter. This is similar to making a strong type.

CREATE TYPE [dbo].[TVP_Items] AS TABLE(
 [ItemID] [int] NOT NULL,
 [Name] [nvarchar](50) NULL
)
GO

Using TVP in T-SQL

Now that you have a table type you have to declare an instance to use it. The following is an quick example that declares an instance of the table type an populates it with some values. Later we will use C# to create a data table that will populate an instance of a table type.

-- Declare instance of TVP_Items Table Type
DECLARE @TVP TVP_Items 
-- Add some sample values into our instance of Table Type.
INSERT INTO @TVP (ItemID, Name) VALUES (1, 'Hat'), (2, 'T-Shirt'), 
(3, 'Football'), (4, 'Jersey')
-- show values that exist in table type instance.
SELECT * FROM @TVP

Using TVP in Stored Procedure

In order to use table value parameters in a stored procedure you have to declare an instance of the table type and specify it as read-only. It is mandatory for the table value parameter to be read-only so you cannot modify the data inside of the table type variable inside the stored procedure.

Below we will insert the data in the table value parameter into the dbo.items table.

CREATE PROCEDURE [dbo].[InsertItemsTVP] @ItemTVP TVP_Items READONLY
AS
BEGIN
 INSERT INTO dbo.Items (ItemID, Name)
 SELECT ItemID, Name
 FROM @ItemTVP
END
GO

Table Value Parameters in .NET (C#)

The following code below generates a data table in C# and it includes four rows. A data table is a common data type used to simulate a table. This data table will be used as our table value parameter and will be used by the stored procedure created above. The data table is not the only type that can be used for table value parameters in C#. The DataReader and list types are also acceptable.

            
DataTable _dt;
// create data table to insert items
_dt = new DataTable("Items");
_dt.Columns.Add("ItemID", typeof(string));
_dt.Columns.Add("Name", typeof(string));
_dt.Rows.Add(4, "SuperBowl 9 Hat");
_dt.Rows.Add(5, "SuperBowl 10 T-Shirt");
_dt.Rows.Add(6, "SuperBowl 13 Towel");
_dt.Rows.Add(7, "SuperBowl 14 Helmet");

Now that we have our data table created we can move on to the data access code. The majority of the code listed below will be the same for the majority of your data access code. The only difference is we will specify that the input type is sql data type as structured and we will pass in our data table to the input parameter. The two lines you need to focus on are underlined in the code section below.

SqlConnection con;
// modify connection string to connect to your database
string conStr = "Server=localhost;Database=MSSQLTIPS;Trusted_Connection=True;";
con = new SqlConnection(conStr);
 con.Open();
using (con)
{                
// Configure the SqlCommand and SqlParameter.
SqlCommand sqlCmd = new SqlCommand("dbo.InsertItemsTVP", con);
sqlCmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvpParam = sqlCmd.Parameters.AddWithValue("@ItemTVP", _dt); //Needed TVP tvpParam.SqlDbType = SqlDbType.Structured; //tells ADO.NET we are passing TVP
sqlCmd.ExecuteNonQuery();
 }
con.Close();

SQL Profiler

When you use this tip you can setup SQL Server Profiler to capture the .NET calls. You will see the following three calls. You should notice that they are very similar to the T-SQL calls above.

SQL Profiler

Next Steps
  • Check out my blogfor more on SQL Server
  • Click hereto download the sample code used in this tip.
  • Check out several linkson Table Value Parameters
  • Click herefor an TVP example for Data Warehouse
  • Click here for an ASP.NET example using Table Value Paramerters

from:http://www.mssqltips.com/sqlservertip/2112/table-value-parameters-in-sql-server-2008-and-net-c/

 

Top 50 .Net Framework Interview and General FAQs

Q 1 What Is CLR? 
CLR is a runtime environment. Code that we develop with language compiler that targets the runtime is called managed code. Programmers write code in any .Net language, compile their programs into IL in a portable executable file that can then be managed and executed by CLR. The cross-language integration is possible because language compilers and tools that target the runtime use a common type system defined by the runtime, and they follow the runtime’s rules for defining new types, as well as for creating, using, persisting, and binding to types.
Q 2 What is CLR HOST? 
Basically, the CLR acts as a library that can be loaded and “hosted” by a process. You can develop an app that loads and hosts the CLR if you wish; that would allow your app to contain a whole CLR virtual machine, load assemblies and run .NET managed code all within it.
SQL Server 2008, for example, can do this. You can write .NET code that is stored in a SQL Server database and run from within the SQL Server database engine. SQL Server is hosting the CLR to achieve that.
Q 3 What is CTS? 
The common type system defines how types are declared, used, and managed in the common language runtime, and is also an important part of the runtime’s support for cross-language integration. The common type system performs the following functions:
Establishes a framework that helps enable cross-language integration, type safety, and high-performance code execution.
Provides an object-oriented model that supports the complete implementation of many programming languages.
Defines rules that languages must follow, which helps ensure that objects written in different languages can interact with each other.
Provides a library that contains the primitive data types (such as Boolean, Byte, Char, Int32, and UInt64) used in application development. All types in the .NET Framework are either value types or reference types.
Value types are data types whose objects are represented by the object’s actual value. If an instance of a value type is assigned to a variable, that variable is given a fresh copy of the value.
Reference types are data types whose objects are represented by a reference (similar to a pointer) to the object’s actual value. If a reference type is assigned to a variable, that variable references (points to) the original value. No copy is made.Classes,Structures,Enumerations,Interfaces,Delegates .
Q 4 What is CLS? 
.Net framework uses CLS to fully interact with others objects written in other languages. It is set of guidelines for languages to follow so that it can communicate with other .NET languages in seamless manner.
This is a subset of CTS which all .Net languages are expected to support.
Q 5 What is an Intermediate Language? 
MSIL is the CPU independent set of instructions which contains instructions of loading, storing, initializing and calling functions. By using Metadata and CTS, MSIL allows true cross language integration. CIL is an object-oriented assembly language, and is entirely stack-based. Its byte code is translated into native code or — most commonly — executed by a virtual machine.
Q 6 What is Just In Time Compiler? 
JIT compiler converts MSIL to native code on demand at application runtime, When the contents of an assembly are loaded and executed. Because CLR supplies a JIT compiler for each supported CPU architecture, Developers can build a set of MSIL assemblies that can be JIT compiled and run on different machine architecture.
Q 7 What is Portable executable (PE)? 
Metadata is stored in one section of a .NET Framework portable executable (PE) file, while Microsoft intermediate language (MSIL) is stored in another section of the PE file. The metadata portion of the file contains a series of table and heap data structures. The MSIL portion contains MSIL and metadata tokens that reference the metadata portion of the PE file.
Q 8 What is Managed Code? 
In .NET Framework Managed Code runs within the .Net Framework’s CLR and benefits from the services provided by the CLR. When we compile the managed code, the code gets compiled to an intermediate language (MSIL) and an executable is created. When a user runs the executable the Just In Time Compiler of CLR compiles the intermediate language into native code specific to the underlying architecture. Since this translation happens by the managed execution environment (CLR), the managed execution environment can make guarantees about what the code is going to do, because it can actually reason about it. It can insert traps and sort of protection around, if it’s running in a sandboxed environment, it can insert all the appropriate garbage collection hooks, exception handling, type safety, array bounce, index checking and so forth.
Q 9 What is Unmanaged Code? 
“Code that is directly executed by the Operating System is known as un-managed code. Typically applications written in VB 6.0, C++, C, etc are all examples of unmanaged code. Unmanaged code typically targets the processor architecture and is always dependent on the computer architecture. Unmanaged code is always compiled to target a specific architecture and will only run on the intended platform. This means that if you want to run the same code on different architecture then you will have to recompile the code using that particular architecture. Unmanaged code is always compiled to the native code which is architecture specific. When we compile unmanaged code it gets compiled into a binary X86 image. And this image always depends on the platform on which the code was compiled and cannot be executed on the other platforms that are different that the one on which the code was compiled. Unmanaged code does not get any services from the managed execution environment.
In unmanaged code the memory allocation, type safety, security, etc needs to be taken care of by the developer. This makes unmanaged code prone to memory leaks like buffer overruns and pointer overrides and so forth.
Unmanaged executable files are basically a binary image, x86 code, loaded into memory. The program counter gets put there and that’s the last the Operating System knows. There are protections in place around memory management and port I/O and so forth, but the system doesn’t actually know what the application is doing.”
Unmanaged Code example like C++, Win32, and COM which compiled into native so they not managed by .net runtime.but as you spend alot of time and money to build them .Net provide Unmanaged Interoperability.
so you can use them into your application and here the word Managed are came into the picture ie the runtime allow to use them but it said i will not managed them its your job to manage them one service that runtime provide to managed code is Garbage Collector its know how to control the lifetime of .net object and memory but it did not know how to clear resource allocated by unmanaged code. so this called unmanaged code and this your responsibility to clear the resource allocated by unmanaged code via implementing IDisposable interface for example.
Q 10 What is Garbage Collector? 
The garbage collector manages the allocation and release of memory for your application.
Each time you create a object, the CLR allocates memory for the object from the managed heap.
The garbage collector’s optimizing engine determines the best time to perform a collection, based upon the allocations being made.. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory.
Q 11 What is a Strong Name? 
A strong name consists of the assembly’s identity — its simple text name, version number, and culture information (if provided) — plus a public key and a digital signature.
You can use strong naming to ensure that when you load a DLL you get exactly the DLL you were expecting and not some other DLL that happens to have the same name.
Strong names guarantee name uniqueness by relying on unique key pairs. No one can generate the same assembly name that you can, because an assembly generated with one private key has a different name than an assembly generated with another private key.
Q 12 What are the steps to create Strong Name? 
Open .net command prompt.
Go to the folder containing DLL.
Type sn -k test.snk, you can use any file name instead of test.
This will create test .snk file in that folder.
Open the assemblyinfo.cs file of project.
Type file path in this tag [assembly:AssemblyKeyFile@”C:\Test\bin\Debug\test.snk”)]
Build application, finally your strong name created for your DLL.
Q 13 What are the Problems faced using Strong Name? 
Requires Exact Match of the strong name key used
Cannot Lose Private Key – if lost we need to create the whole process again
Q 14 What is Program Database? 
PDB files commonly have .pdb extention.When you create a class library project then after compilation,a .dll and .pdb file is created in ProjectRootFolder\bin\Debug.The created pdb file is program database for this project.
Q 16 What is an Assembly? 
A chunk of (precompiled) code that can be executed by the .NET runtime environment. A .NET program consists of one or more assemblies. An assembly is a collection of types and resources that forms a logical unit of functionality.
When you compile an application, the MSIL code created is stored in an assembly .
Assemblies include both executable application files that you can run directly from Windows without the need for any other programs (these have a .exe file extension), and libraries (which have a .dll extension) for use by other applications.
There are two kind of assemblies in .NET;
private shared
Private assemblies are simple and copied with each calling assemblies in the calling assemblies folder.
Shared assemblies (also called strong named assemblies) are copied to a single location (usually the Global assembly cache). For all calling assemblies within the same application, the same copy of the shared assembly is used from its original location. Hence, shared assemblies are not copied in the private folders of each calling assembly. Each shared assembly has a four part name including its face name, version, public key token and culture information. The public key token and version information makes it almost impossible for two different assemblies with the same name or for two similar assemblies with different version to mix with each other.
Q 17 What are the Contents of an Assembly? 
The assembly manifest, which contains assembly metadata.Type metadata,MSIL code that implements the types,A set of resources.
Q 18 What are Types of an Assemblies? 
Private Assembly: – An assembly is used only for a particular application. It is stored in the application’s directory otherwise in the application’s sub directory. There is no version constraint in private assembly.
Public/shared Assembly:- It has version constraint. This public assembly is stored inside the global assembly cache or GAC.GAC contains a collection of shared assemblies.
A .NET Framework assembly containing resources specific to a given language. Using satellite assemblies, you can place the resources for different languages in different assemblies, and the correct assembly is loaded into memory only if the user elects to view the application in that language.”
Q 19 What is a Satellite assembly? 
A satellite assembly is a .NET Framework assembly containing resources specific to a given language. Using satellite assemblies, you can place resources for different languages in different assemblies, and the correct assembly is loaded into memory only if the user selects to view the application in that language.
Q 20 What are Steps to Create Satellite Assembly? 
Create a folder with a specific culture name (for example, en-US) in the application’s bin\debug folder.
Create a .resx file in that folder. Place all translated strings into it.
Create a .resources file by using the following command from the .NET command prompt. (localizationsample is the name of the application namespace. If your application uses a nested namespace structure like MyApp.YourApp.MyName.YourName as the type of namespace, just use the uppermost namespace for creating resources files—MyApp.)
resgen Strings.en-US.resx LocalizationSample.
Strings.en-US.resources
al /embed:LocalizationSample.Strings.en-US.resources
/out:LocalizationSample.resources.dll /c:en-US
The above step will create two files, LocalizationSample.Strings.en-US.resources and LocalizationSample.resources.dll. Here, LocalizationSample is the name space of the application.
In the code, find the user’s language; for example, en-US. This is culture specific.
Give the assembly name as the name of .resx file. In this case, it is Strings.
Q 21 What is an Assembly Loader? 
The first thing the .NET assembly loader checks is whether the assembly is strongly signed. If it is, it will start its search in the Global Assembly Cache .
The loader will search for a policy file named in the format of:
policy.AssemblyMajorVersion.AssembyMinorVersion.AssemblyName
For example:
Policy.1.2.MyAssembly
If such a file exists it will look inside of it if the version of the assembly that we are trying to load matches the version/versions range written in the policy file. If it does, it will try to load the assembly with the version specified there. If no such policy file exists, it will try to load the assembly from the GAC.
If it will fail to find it in the GAC, it will start to search in the system’s search path.
In web applications it will also include the application’s Bin directory in the search path.
You can manually add folders to an AppDomain’s search path by using the “AppendPrivatePath” method.
Q 22 What is Multi Module Assembly or Assembly Linker? 
An assembly is called Multi Module assembly if it refers to multiple files. It can be combinations of modules written in different languages. When we link different modules into final assembly, the hash of each module is recorded in the manifest file.
link.exe is used to link multiple modules
as
c:\>more a1.vb
c:\>more b1.cs
c:\>vbc /t:module a1.vb
c:\>csc /addmodule:a1.netmodule /t:module b1.cs
c:\>link /entry:MainClinetApp.Main /out:main.exe b1.netmodule a1.module
Q 23 What is an Assembly Manifest? 
Assembly Manifest contains
Assembly Name,
Version number,
Culture,
Strong Name Information,
List of all files in the assembly,
Type Reference information,
Information on referenced assemblies.
Q 24 What is a Metadata? 
COM provided a step towards solving this problem. The .NET Framework makes component interoperation even easier by allowing compilers to emit additional declarative information into all modules and assemblies. This information, called metadata, helps components to interact seamlessly.
Metadata is binary information describing your program that is stored either in a common language runtime portable executable (PE) file or in memory. When you compile your code into a PE file, metadata is inserted into one portion of the file, and your code is converted to Microsoft intermediate language (MSIL) and inserted into another portion of the file. Every type and member that is defined and referenced in a module or assembly is described within metadata. When code is executed, the runtime loads metadata into memory and references it to discover information about your code’s classes, members, inheritance, and so on.
Q 25 What is a Base class in .Net? 
A base class, in the context of C#, is a class that is used to create, or derive, other classes. Classes derived from a base class are called child classes, subclasses or derived classes. A base class does not inherit from any other class and is considered parent of a derived class. Base class members (constructor, an instance method or instance property accessor) are accessed in derived class using the “base” keyword.
Base classes are automatically instantiated before derived classes.
Derived class can communicate to the base class during instantiation by calling the base class constructor with a matching parameter list.
Base class members can be accessed from the derived class through an explicit cast.
Since a base class itself can be a derived class, a class may have many base classes.
Members of a derived class can access the public, protected, internal and protected internal members of a base class.
Due to the transitive nature of inheritance, although a derived class has only one base class, it inherits the members declared in the parent of the base class.
By declaring a method in base class as virtual, the derived class can override that method with its own implementation. Both the overridden and overriding method and property must have the same access-level modifiers such as virtual, abstract or override.
When the keyword “abstract” is used for a method, it should be overridden in any nonabstract class that directly inherits from that class.
Abstract base classes are created using the “abstract” keyword in its declaration and are used to prevent direct initiation using the “new” keyword. They can only be used through derived classes that implement abstract methods.
A base class can prevent other classes from inheriting from it by declaring all the members as “sealed.”
Base class members can be hidden in a derived class by using the keyword “new” to indicate that the member is not intended to be an override of the base member. If “new” is not used, the compiler generates a warning.
Q 26 What is Full Assembly Reference? 
Full Assembly reference: A full assembly reference includes the assembly’s text name, version, culture, and public key token (if the assembly has a strong name). A full assembly reference is required if you reference any assembly that is part of the common language runtime or any assembly located in the global assembly cache.
Partial Assembly reference: We can dynamically reference an assembly by providing only partial information, such as specifying only the assembly name. When you specify a partial assembly reference, the runtime looks for the assembly only in the application directory. We can make partial references to an assembly in your code one of the following ways:
Use a method such as System.Reflection.Assembly.Load and specify only a partial reference. The runtime checks for the assembly in the application directory.
Use the System.Reflection.Assembly.LoadWithPartialName method and specify only a partial reference. The run time checks for the assembly in the application directory and in the global assembly cache.
Q 28 What is an Assembly Qualified Name? 
Type objType = typeof(System.Array);
// Print the full assembly name.
Console.WriteLine (“Full assembly name:\n {0}.”,
objType.Assembly.FullName.ToString());
// Print the qualified assembly name.
Console.WriteLine (“Qualified assembly name:\n {0}.”,
objType.AssemblyQualifiedName.ToString());
Q 29 What is ILDASM (Intermediate Language Disassembler)? 
The Ildasm.exe parses any .NET Framework .exe or .dll assembly, and shows the information in human-readable format. Ildasm.exe shows more than just the Microsoft intermediate language (MSIL) code — it also displays namespaces and types, including their interfaces. You can use Ildasm.exe to examine native .NET Framework assemblies, such as Mscorlib.dll, as well as .NET Framework assemblies provided by others or created yourself. Most .NET Framework developers will find Ildasm.exe indispensable.http://msdn.microsoft.com/en-us/library/aa309387(v=vs.71).aspx
Q 30 What is Global Assembly Cache? 
The global assembly cache stores assemblies specifically designated to be shared by several applications on the computer.
Q 31 What is an Attribute? 
Attributes provide a powerful method of associating declarative information with C# code (types, methods, properties, and so forth). Once associated with a program entity, the attribute can be queried at run time and used in any number of ways.
Q 32 What is Serialization & Deserialization? 
Serialization is the process of converting the state of an object into a form that can be persisted in a storage medium or transported across the processes/machines. The opposite of serialization is deserialization which is a process that converts the outcome of serialization into the original object.
Q 33 Where Serialization is used? 
Communication: If you have two machines that are running the same code, and they need to communicate, an easy way is for one machine to build an object with information that it would like to transmit, and then serialize that object to the other machine. It’s not the best method for communication, but it gets the job done.
Persistence: If you want to store the state of a particular operation in a database, it can be easily serialized to a byte array, and stored in the database for later retrieval.
Deep Copy: If you need an exact replica of an Object, and don’t want to go to the trouble of writing your own specialized clone() class, simply serializing the object to a byte array, and then de-serializing it to another object achieves this goal.
Caching: Really just an application of the above, but sometimes an object takes 10 minutes to build, but would only take 10 seconds to de-serialize. So, rather than hold onto the giant object in memory, just cache it out to a file via serialization, and read it in later when it’s needed.
Serialization is useful any time you want to move a representation of your data into or out of your process boundary.
Saving an object to disk is a trivial example you’ll see in many tutorials.
More commonly, serialization is used to transfer data to and from a web service, or to persist data to or from a database.
Q 34 What are the types of Serialization available in .net? 
Serialization can be Binary,SOAP or XML.
Q 35 What is Binary Serialization? 
Binary serialization is the process where you convert your .NET objects into byte stream. In binary serialization all the public, private, even those which are read only, members are serialized and converted into bytes. So when you want a complete conversion of your objects to bytes then one can make use of binary serialization.In XML serialization only the public properties and fields of the objects are converted into XML. The private members are not taken into consideration in XML serialization.
Similar to XML serialization. When you serialize object to SOAP format it conforms to the SOAP specification.Binary Serialization: Light and compact used in Remoting
SOAP Serialization : Interoperable use SOAP and used in web Services
XML Serialization : Custom Serialization .
Q 36 What are the Advantages & Disadvantages of Binary Serialization? 
Advantages of Binary Serialization
Object can be de-serialized from the same data you serialized it to.
Enhanced performance as it is faster and even more powerful in the sense that it provides support for complex objects, read only properties and even circular references.
Disadvantage of Binary Serialization: It is not easily portable to another platform.
Q 37 What is SOAP Serialization? 
To support SOAP serialization, the .NET Framework provides the SoapFormatter class. This class is defined in the System.Runtime.Serialization.Formatters.Soap namespace that is part of the System.Runtime.Serialization.Formatters.Soap.dll assembly. In order to use The SoapFormatter class, you must reference this assembly. Then, you can create an object and initialize it as you see fit. Before saving it, as always, create a Stream-based object that would indicate the name (and location) of the file and the type of action to perform. Then, declare a SoapFormatter variable using its default constructor. To actually save the object, call the Serialize() method of this class. This method uses the same syntax as that of the BinaryFormatter class: it takes two arguments. The first is a Stream-based object. The second is the object that needs to be serialized.Typically the serialization process consists of creation of the serializer, opening of the stream and invocation of the serializer.
Q 38 What is Advantages of SOAP Serialization? 
If you want full Type fidelity, and the “stability” that you are talking about you should use Soap Serialization. Soap Serialization preserves the
full type information.
XML Serialization is intended more for interoperability with other Operating Systems, and does not preserve all type information.
Q 39 What is a XML Serialization? 
XML serialization serializes only the public fields and property values of an object into an XML stream. XML serialization does not include type information. For example, if you have a Book object that exists in the Library namespace, there is no guarantee that it is deserialized into an object of the same type.XML serialization does not convert methods, indexers, private fields, or read-only properties (except read-only collections). To serialize all an object’s fields and properties, both public and private, use the DataContractSerializer instead of XML serialization.
Q 40 What are the Advantages of XML Serialization? 
The advantages of XML Serialization are as follows:
· XML based
· Support for cross platforms
· Easily readable and editable
Q 41 >What is Custom Serialization? 
Custom serialization is the process of controlling the serialization and deserialization of a type. By controlling serialization, it is possible to ensure serialization compatibility, which is the ability to serialize and deserialize between versions of a type without breaking the core functionality of the type. For example, in the first version of a type, there may be only two fields. In the next version of a type, several more fields are added. Yet the second version of an application must be able to serialize and deserialize both types. The following sections describe how to control serialization.
Q 42 What is a Namespace? 
The namespace keyword is used to declare a scope that contains a set of related objects. You can use a namespace to organize code elements and to create globally unique types.
Q 43 What is GUID? 
A Globally Unique Identifier is a unique reference number used as an identifier.
The term GUID typically refers to various implementations of the universally unique identifier (UUID) standard.GUIDs are usually stored as 128-bit values, and are commonly displayed as 32 hexadecimal digits with groups separated by hyphens, such as {21EC2020-3AEA-4069-A2DD-08002B30309D}.the total number of unique such GUIDs is 2122 or 5.3×1036.
Q 44 What is a Formatter? 
A formatter is an object that is responsible for encoding and serializing data into messages on one end, and deserializing and decoding messages into data on the other end.
Q 45 What is a Binary Formatter?
Serializes and deserializes an object, or an entire graph of connected objects, in binary format.
[ComVisibleAttribute(true)]
public sealed class BinaryFormatter : IRemotingFormatter, Iformatter
Q 46 What is a SOAP Formatter? 
Serializes and deserializes an object, or an entire graph of connected objects, in SOAP format.
Q 47 What is Reflection? 
Reflection provides objects (of type Type) that describe assemblies, modules and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection enables you to access them.
Reflection is useful in the following situations:
When you have to access attributes in your program’s metadata.
Retrieving Information Stored in Attributes.
For examining and instantiating types in an assembly.
For building new types at runtime. Use classes in System.Reflection.Emit.
For performing late binding, accessing methods on types created at run time.
Q 48 What is Thread and Process? 
A process, in the simplest terms, is an executing program. One or more threads run in the context of the process. A thread is the basic unit to which the operating system allocates processor time. A thread can execute any part of the process code, including parts currently being executed by another thread.
Q 49 What are the difference between a Dll and an Exe? 
EXE:
It’s a executable file
When loading an executable, no export is called, but only the module entry point.
When a system launches new executable, a new process is created
The entry thread is called in context of main thread of that process.
DLL:
It’s a Dynamic Link Library
There are multiple exported symbols.
The system loads a DLL into the context of an existing process.
Q 50 What are Globalization and Localization? 
Globalization is the process of designing and developing applications that function for multiple cultures. Localization is the process of customizing your application for a given culture and locale.
References:

from:http://www.sqlservercentral.com/blogs/querying-microsoft-sql-server/2014/04/16/top-50-net-framework-interview-and-general-faqs/

C# Language Features, From C# 2.0 to 4.0

Contents

Introduction

This article discusses the language features introduced in C# 2.0, 3.0, and 4.0. The purpose of writing this article is to have a single repository of  all the new language features introduced over the last seven years and to illustrate (where applicable) the advantages of the new features. It is  not intended to be a comprehensive discussion of each feature, for that I have links for further reading. The impetus for this article is mainly because  I could not find a single repository that does what this article does. In fact, I couldn’t even find a Microsoft webpage that describes them.  Instead, I had to rely on the universal authority for everything, Wikipedia, which has a couple  nice tables on the matter.

C# 2.0 Features

Generics

First off, generics are not like C++ templates. They primarily provide for strongly typed collections.

Without Generics

Collapse | Copy Code
public void WithoutGenerics()
{
  ArrayList list = new ArrayList();

  // ArrayList is of type object, therefore essentially untyped.
  // Results in boxing and unboxing of value types
  // Results in ability to mix types which is bad practice.
  list.Add(1);
  list.Add("foo");
}

Without generics, we incur a “boxing” penalty because lists are of type “object”, and furthermore, we can quite easily add incompatible types to a list.

With Generics

Collapse | Copy Code
public void WithGenerics()
{
  // Generics provide for strongly typed collections.
  List<int> list = new List<int>();
  list.Add(1); // allowed
  // list.Add("foo"); // not allowed
}

With generics we are prevented from using a typed collection with an incompatible type.

Constraints and Method Parameters and Return Types

Generics can also be used in non-collection scenarios, such as enforcing the type of a parameter or return value. For example, here we create a generic method (the reason we don’t create  a generic MyVector will be discussed in a minute:

Collapse | Copy Code
public class MyVector
{
    public int X { get; set; }
    public int Y { get; set; }
}

class Program
{
    public static T AddVector<T>(T a, T b)
      where T : MyVector, new()
    {
      T newVector = new T();
      newVector.X = a.X + b.X;
      newVector.Y = a.Y + b.Y;

      return newVector;
    }

    static void Main(string[] args)
    {
     MyVector a = new MyVector();
     a.X = 1;
     a.Y = 2;
     MyVector b = new MyVector();
     b.X = 10;
     b.Y = 11;
     MyVector c = AddVector(a, b);
     Console.WriteLine(c.X + ", " + c.Y);
   }
}

Notice the constraint. Read more about constraints here.  The constraint is telling the compiler that the generic parameter must be of type MyVector, and that it is an object (the “new()“) constraint,  rather than a value type. The above code is not very helpful because it would require writing an “AddVector” method for vectors of different types (int, double, float, etc.)

What we can’t do with generics (but could with C++ templates) is perform operator functions on generic types. For example, we can’t do this:

Collapse | Copy Code
public class MyVector<T>
{
  public T X { get; set; }
  public T Y { get; set; }

  // Doesn't work:
  public void AddVector<T>(MyVector<T> v)
  {
    X = X + v.X;
    Y = Y + v.Y;
  }
}

This results in a “operator ‘+=’ cannot be applied to operands of type ‘T’ and ‘T'” error! More on workarounds for this later.

Factories

You might see generics used in factories. For example:

Collapse | Copy Code
public static T Create<T>() where T : new()
{
  return new T();
}

The above is a very silly thing to do, but if you are writing an Inversion of Control layer, you might be doing some complicated things (like loading  assemblies) based on the type the factory needs to create.

Partial Types

Partial types can be used on classes, structs, and interface. In my opinion, partial types were created to separate out tool generated code from  manually written code. For example, the Visual Studio form designer generates the code-behind for the UI layout, and to keep this code stable and  independent from your manually written code, such as the event handlers, Visual  Studio creates two separate files and indicates that the same class is of partial type. For example, let’s say we have two separate files:

File 1:

Collapse | Copy Code
public partial class MyPartial
{
  public int Foo { get; set; }
}

File 2:

Collapse | Copy Code
public partial class MyPartial
{
  public int Bar { get; set; }
}

We can use the class, which has been defined in two separate files:

Collapse | Copy Code
public class PartialExample
{
  public MyPartial foobar;

  public PartialExample()
  {
    foobar.Foo = 1;
    foobar.Bar = 2;
  }
}

Do not use partial classes to implement a model-view-controller pattern! Just because you can separate the code into different files, one  for the model, one for the view, and one view the controller, does not mean you are implementing the MVC pattern correctly!

The old way of handling tool generated code was typically to put comments in the code like:

Collapse | Copy Code
// Begin Tool Generated Code: DO NOT TOUCH
   ... code ...
// End Tool Generated Code

And the tool would place its code between the comments.

Anonymous Methods

Read more.

Anonymous methods let us define the functionality of a delegate (such as an event) inline rather than as a separate method.

The Old Way

Before anonymous delegates, we would have to write a separate method for the delegate implementation:

Collapse | Copy Code
public class Holloween
{
  public event EventHandler ScareMe;

  public void OldBoo()
  {
    ScareMe+=new EventHandler(DoIt);
  }

  public void Boo()
  {
    ScareMe(this, EventArgs.Empty);
  }

  public void DoIt(object sender, EventArgs args)
  {
    Console.WriteLine("Boo!");
  }
}

The New Way

With anonymous methods, we can implement the behavior inline:

Collapse | Copy Code
public void NewBoo()
{
  ScareMe += delegate(object sender, EventArgs args) { Console.WriteLine("Boo!"); };
}

Async Tasks

We can do the same thing with the Thread class:

Collapse | Copy Code
public void AsyncBoo()
{
  new Thread(delegate() { Console.WriteLine("Boo!"); }).Start();
}

Note that we cast the method as a “delegate()”–note the ‘()’–because there are two delegate forms and we have to specify the parameterless delegate form.

Updating the UI

My favorite example is calling the main application thread from a worker thread to update a UI component:

Collapse | Copy Code
/// <summary>
/// Called from some async process:
/// </summary>
public void ApplicationThreadBoo()
{
  myForm.Invoke((MethodInvoker)delegate { textBox.Text = "Boo"; });
}

Iterators

Read more.

Iterators reduce the amount of code we have to write to iterate over a custom collection.

The Old Way

Previous to C# 2.0, we had to implement the IEnumerator interface, supplying the Current, MoveNext, and Reset operations manually:

Collapse | Copy Code
public class DaysOfWeekOld : IEnumerable
{
  protected string[] days = new string[] { "Monday", "Tuesday", "Wednesday", "Thursday",
                                             "Friday", "Saturday", "Sunday" };

  public int Count { get { return days.Length; } }
  public string this[int idx] { get { return days[idx]; } }

  public IEnumerator GetEnumerator()
  {
    return new DaysOfWeekEnumerator(this);
  }
}

public class DaysOfWeekEnumerator : IEnumerator
{
  protected DaysOfWeekOld dow;
  protected int pos = -1;

  public DaysOfWeekEnumerator(DaysOfWeekOld dow)
  {
    this.dow = dow;
  }

  public object Current
  {
    get { return dow[pos]; }
  }

  public bool MoveNext()
  {
    ++pos;

    return (pos < dow.Count);
  }

  public void Reset()
  {
    pos = -1;
  }
}

The New Way

In the new approach, we can use the yield keyword to iterate through the collection:

Collapse | Copy Code
public class DaysOfWeekNew : IEnumerable
{
  protected string[] days = new string[] { "Monday", "Tuesday", "Wednesday", "Thursday",
                                            "Friday", "Saturday", "Sunday" };

  public IEnumerator GetEnumerator()
  {
    for (int i = 0; i < days.Length; i++)
    {
      yield return days[i];
    }
  }
}

This is much more readable and also ensures that we don’t access elements in the collection beyond the number of items in the collection.

We can also implement a generic enumerator, which provides a type safe iterator, but requires us to implement both generic and non-generic GetEnumerator method:

Collapse | Copy Code
public class DaysOfWeekNewGeneric : IEnumerable<string>
{
  protected string[] days = new string[] { "Monday", "Tuesday", "Wednesday", "Thursday",
                                            "Friday", "Saturday", "Sunday" };

  IEnumerator IEnumerable.GetEnumerator()
  {
    return Enumerate();
  }

  public IEnumerator<int> GetEnumerator()
  {
    return Enumerate();
  }

  public IEnumerator<string> Enumerate()
  {
    for (int i = 0; i < days.Length; i++)
    {
      yield return days[i];
    }
  }
}

So, for example, in the non-generic version, I could write:

Collapse | Copy Code
DaysOfWeekNew dow2 = new DaysOfWeekNew();

foreach (string day in dow2)
{
  Console.WriteLine(day);
}

which is perfectly valid, but I could also write:

Collapse | Copy Code
DaysOfWeekNew dow2 = new DaysOfWeekNew();

foreach (int day in dow2)
{
  Console.WriteLine(day);
}

The error in casting from a string to an integer is caught at runtime, not compile time. Using a generic IEnumerable<T>,  an improper cast is caught at compile time and also by the IDE:

Collapse | Copy Code
DaysOfWeekNewGeneric dow3 = new DaysOfWeekNewGeneric();

foreach (int day in dow3)
{
  Console.WriteLine(day);
}

The above code is invalid and generates the compiler error:

“error CS0030: Cannot convert type ‘string’ to ‘int'”

Thus, the implementation of generic iterators in C# 2.0 increases readability and type safety when using iterators.

Nullable Types

Read more.

Nullable types allow a value type to take on an additional “value”, being “null”. I’ve found this primarily useful when working with data tables. For example:

Collapse | Copy Code
public class Record
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int? ParentID { get; set; } 
}

public class NullableTypes
{
  protected DataTable people;

  public NullableTypes()
  {
    people = new DataTable();

    // Note that I am mixing a C# 3.0 feature here, Object Initializers,
    // with regards to how AllowDBNull is initialized. I'm doing because I think
    // the example is more readable, even though not C# 2.0 compilable.

    people.Columns.Add(new DataColumn("ID", typeof(int)) {AllowDBNull=false});
    people.Columns.Add(new DataColumn("Name", typeof(string)) { AllowDBNull = false });
    people.Columns.Add(new DataColumn("ParentID", typeof(int)) { AllowDBNull = true });

    DataRow row = people.NewRow();
    row["ID"] = 1;
    row["Name"] = "Marc";
    row["ParentID"] = DBNull.Value; // Marc does not have a parent!
    people.Rows.Add(row);
  }

  public Record GetRecord(int idx)
  {
    return new Record()
    {
      ID = people.Rows[idx].Field<int>("ID"),
      Name = people.Rows[idx].Field<string>("Name"),
      ParentID = people.Rows[idx].Field<int?>("ParentID"),
    };
  }
}

In the above example, the Field extension method (I’ll discuss extension methods later) converts DBNull.Value automatically to a “null“, which in this  schema is a valid foreign key value.

You will also see nullable types used in various third party frameworks to represent “no value.”  For example, in the DevExpress framework, a checkbox  can be set to false, true, or no value. The reason for this is again to support mapping a control directly to a structure that backs a table with  nullable fields. That said, I think you would most likely see nullable types in ORM implementations.

Private Setters (properties)

Read more.

A private setter exposes a property as read-only, which is different from designating the property as readonly. With a field designated as readonly,  it can only be initialized during construction or in the variable initializer. With a private setter, the property can be exposed as readonly to the  outside world the class implementing the property can still write to it:

Collapse | Copy Code
public class PrivateSetter
{
  public int readable;
  public readonly int readable2;

  public int Readable
  {
    get { return readable; }
    // Accessible only by this class.
    private set { readable = value; }
  }

  public int Readable2
  {
    get { return readable2; }
    // what would the setter do here?
  }

  public PrivateSetter()
  {
    // readonly fields can be initialized in the constructor.
    readable2 = 20;
  }

  public void Update()
  {
    // Allowed:
    Readable = 10;
    // Not allowed:
    // readable2 = 30;
  }
}

Contrast the above implementation with C# 3.0’s auto-implemented properties, which I discuss below.

Method Group Conversions (delegates)

I must admit to a “what the heck is this?” experience for this feature. First (for my education) a “method group” is a set of methods of the same name.  In other words, a method with multiple overloads. This post was very helpful. I stumbled across this post that explained method group conversion with delegates. This  also appears to have to do with covariance and contravariance, features of C# 4.0. Read more here. But let’s try the basic concept,  which is to assign a method to a delegate without having to use “new” (even though behind the scenes, that’s apparently what the IL is emitting).

The Old Way

Collapse | Copy Code
public class MethodGroupConversion
{
  public delegate string ChangeString(string str);
  public ChangeString StringOperation;

  public MethodGroupConversion()
  {
    StringOperation = new ChangeString(AddSpaces);
  }

  public string Go(string str)
  {
    return StringOperation(str);
  }

  protected string AddSpaces(string str)
  {
    return str + " ";
  }
}

The New Way

We replace the constructor with a more straightforward assignment:

Collapse | Copy Code
public MethodGroupConversion()
{
  StringOperation = AddSpaces;
}

OK, that seems simple enough.

C# 3.0 Features

Implicitly Typed Local Variables

Read more.

The “var” keyword is a new feature of C# 3.0. Using the “var” keyword, you are relying on the compiler to infer the variable type  rather than explicitly defining it. So, for example, instead of:

Collapse | Copy Code
public void Example1()
{
  // old:
  Dictionary<string, int> explicitDict = new Dictionary<string, int>();

  // new:
  var implicitDict = new Dictionary<string, int>();
}

While it seems like syntactical sugar, the real strength of implicit types is its use in conjunction with anonymous types (see below.)

Restrictions

Note the phrase “local variables” in the heading for this section. Implicitly typed variables cannot be passed to other methods as parameters nor  returned by methods. As Richard Deeming commented below, what I mean by this is that you cannot specify var as a parameter or return type, but you  can call a method with an implicit type of the method’s parameter is an explicit type, and similarly (and more obviously) with return parameters — an explicit return  type can be  assigned to a var.

Object and Collection Initializers

Read more.

The Old Way

Previously, to initialize property values from outside of the class, we would have to write either use a constructor:

Collapse | Copy Code
public Record(int id, string name, int? parentID)
{
  ID = id;
  Name = name;
  ParentID = parentID;
}
...
new Record(1, "Marc", null);

or initialize the properties separately:

Collapse | Copy Code
Record rec=new Record();
rec.ID = 1;
rec.Name = "Marc";
rec.ParentID = null;

The New Way

In its explicit implementation, this simply allow us to initialize properties and collections when we create the object. We’ve already seen examples in the code above:

Collapse | Copy Code
Record r = new Record() {ID = 1, Name = "Marc", ParentID = 3};

More interestingly is how this feature is used to initialize anonymous types (see below) especially with LINQ.

Initializing Collections

Similarly, a collection can be initialized inline:

Collapse | Copy Code
List<Record> records = new List<Record>()
{
  new Record(1, "Marc", null),
  new Record(2, "Ian", 1),
};

Auto-Implemented Properties

In the C# 2.0 section, I described the private setter for properties. Let’s look at the same implementation using auto-implemented properties:

Collapse | Copy Code
public class AutoImplement
{
  public int Readable { get; private set; }
  public int Readable2 { get { return 20; } }

  public void Update()
  {
    // Allowed:
    Readable = 10;
    // Not allowed:
    // Readable2 = 30;
  }
}

The code is a lot cleaner, but the disadvantage is that, for properties that need to fire events or have some other business logic or validation associated  with them, you have to go back to the old way of implementing the backing field manually. One proposed solution to firing property change events for  auto-implemented properties is to use AOP techniques, as written up by Tamir Khason’s Code Project technical blog.

Anonymous Types

Read more.

Anonymous types lets us create “structures” without defining a backing class or struct, and rely on implicit types (vars) and object initializers.  For example, if we have a collection of “Record” objects, we can return a subset of the properties in this LINQ statement:

Collapse | Copy Code
public void Example()
{
  List<Record> records = new List<Record>();
    {
      new Record(1, "Marc", null),
      new Record(2, "Ian", 1),
    };

  var idAndName = from r in records select new { r.ID, r.Name };
}

Here we see how several features come into play at once:

  • LINQ
  • Implicit types
  • Object initialization
  • Anonymous types

If we run the debugger and inspect “idAndName”, we’ll see that it has a value:

Collapse | Copy Code
{System.Linq.Enumerable.WhereSelectListIterator<CSharpComparison.Record,
          <>f__AnonymousType0<int,string>>}

and (ready for it?) the type:

Collapse | Copy Code
System.Collections.Generic.IEnumerable<<>f__AnonymousType0<int,string>> 
   {System.Linq.Enumerable.WhereSelectListIterator<CSharpComparison.Record,
   <>f__AnonymousType0<int,string>>}

Imagine having to explicitly state that type name. We can see advantages of implicit types, especially in conjunction with anonymous types.

Extension Methods

Read more.

Extension methods are a mechanism for extending the behavior of a class external to its implementation.  For example, the String class is  sealed, so we can’t inherit from it, but there’s a lot of useful functions that the String class doesn’t provide. For example, working with Graphviz, I  often need to put quotes around the object name.

Before Extension Methods

Before extension methods, I would probably end up writing something like this:

Collapse | Copy Code
string graphVizObjectName = "\"" + name +"\"";

Not very readable, re-usable, or bug proof (what if name is null?)

With Extension Methods

With extension methods, I can write an extension:

Collapse | Copy Code
public static class StringHelpersExtensions
{
  public static string Quote(this String src)
  {
    return "\"" + src + "\"";
  }
}

(OK, that part looks pretty much the same) – but I would use it like this:

Collapse | Copy Code
string graphVizObjectName = name.Quote();

Not only is this more readable, but it’s also more reusable, as the behavior is now exposed everywhere.

Query Expressions

Read more.

Query expressions seems to be a synonymous phrase for LINQ (Language-Integrated Query). Humorously, the Microsoft website I just referenced has the header  “LINQ Query Expressions.”  Redundant!

Query expressions are written in a declarative syntax and provide the ability to query an enumerable or “queriable” object using complex filters, ordering,  grouping, and joins, very similar in fact to how you would work with SQL and relational data.

As I wrote about above with regards to anonymous types, here’s a LINQ statement:

Collapse | Copy Code
var idAndName = from r in records select new { r.ID, r.Name };

LINQ expressions can get really complex and working with .NET classes and LINQ relies heavily on extension methods. LINQ is far to large a topic (there are whole books on the subject) and is definitely outside the purview of this article!

Left and Right Joins

Joins by default in LINQ are inner joins. I was perusing recently for how to do left and right joins and came across this useful post.

Lambda Expressions

Read more.

Lambda expressions are a fundamental part of working with LINQ. You usually will not find LINQ without lambda expressions. A lambda expression  is an anonymous method (ah ha!) that “can contain expressions and statements, and can be used to create delegates or expression tree types…The left side of  the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block.” (taken from the website referenced above.)

In LINQ, I could write:

Collapse | Copy Code
var idAndName = from r in records 
  where r.Name=="Marc"
  select new { r.ID, r.Name };

and I’d get the names of people with the name “Marc”. With a lambda expression and the extension methods provided for a generic List, I can write:

Collapse | Copy Code
var idAndName2 = records.All(r => r.Name == "Marc");

LINQ and lambda expressions can be combined. For example, here’s some code from an article I recently wrote:

Collapse | Copy Code
var unassoc = from et in dataSet.Tables["EntityType"].AsEnumerable()
  where !(dataSet.Tables["RelationshipType"].AsEnumerable().Any(
     rt => 
       (rt.Field<int>("EntityATypeID") == assocToAllEntity.ID) && 
       (rt.Field<int>("EntityBTypeID") == et.Field<int>("ID"))))
  select new { Name = et.Field<string>("Name"), ID = et.Field<int>("ID") };

LINQ, lambda expressions, anonymous types, implicit types, collection initializers and object initializers all work together to more concisely express  the intent of the code. Previously, we would have to do this with nested for loops and lots of “if” statements.

Expression Trees

Read more.

Let’s revisit the MyVector example. With expression trees, we can however compile type-specific code at runtime that allows us to work with generic numeric types in a performance efficient manner (compare with “dynamic” in C# 4.0, discussed below).

Collapse | Copy Code
public class MyVector<T>
{
  private static readonly Func<T, T, T> Add;

  // Create and cache adder delegate in the static constructor.
  // Will throw a TypeInitializationException if you can't add Ts or if T + T != T 
  static MyVector()
  {
    var firstOperand = Expression.Parameter(typeof(T), "x");
    var secondOperand = Expression.Parameter(typeof(T), "y");
    var body = Expression.Add(firstOperand, secondOperand);
    Add = Expression.Lambda<Func<T, T, T>>(body, firstOperand, secondOperand).Compile();
  }

  public T X { get; set; }
  public T Y { get; set; }

  public MyVector(T x, T y)
  {
    X = x;
    Y = y;
  }

  public MyVector<T> AddVector(MyVector<T> v)
  {
    return new MyVector<T>(Add(X, v.X), Add(Y, v.Y));
  }
}

The above example comes from a post on StackOverflow.

C# 4.0 Features

Dynamic Binding

Read more.

Let’s revisit the MyVector implementation again. With the dynamic keyword, we can defer the operation to runtime when we know the type.

Collapse | Copy Code
public class MyVector<T>
{
  public MyVector() {}

  public MyVector<T> AddVector(MyVector<T> v)
  {
    return new MyVector<T>()
    {
      X = (dynamic)X + v.X,
      Y = (dynamic)Y + v.Y,
    };
  }
}

Because this uses method invocation and reflection, it is very performance inefficient. According to MSDN referenced in the link above: The  dynamic type simplifies access to COM APIs such as the Office Automation APIs, and also to dynamic APIs such as IronPython libraries, and to the HTML Document Object Model (DOM).

Named and Optional Arguments

Read more.

As with the dynamic keyword, the primary purpose of this is to facilitate calls to COM. From the MSDN link referenced above:

Named arguments enable you to specify an argument for a particular parameter by associating the argument with the parameter’s name rather than with  the parameter’s position in the parameter list. Optional arguments enable you to omit arguments for some parameters. Both techniques can be used with methods,  indexers, constructors, and delegates.

When you use named and optional arguments, the arguments are evaluated in the order in which they appear in the argument list, not the parameter list.

Named and optional parameters, when used together, enable you to supply arguments for only a few parameters from a list of optional parameters.  This capability greatly facilitates calls to COM interfaces such as the Microsoft Office Automation APIs.

I have never used named arguments and I rarely need to use optional arguments, though I remember when I moved from C++ to C#, kicking and screaming  that optional arguments weren’t part of the C# language specification!

Example

We can use named an optional arguments to specifically indicate which arguments we are supplying to a method:

Collapse | Copy Code
public class NamedAndOptionalArgs
{
  public void Foo()
  {
    Bar(a: 1, c: 5);
  }

  public void Bar(int a, int b=1, int c=2)
  {
    // do something.
  }
}

As this example illustrates, we can specify the value for a, use the default value for b, and specify a non-default value for c. While I find named  arguments to be of limited use in regular C# programming, optional arguments are definitely a nice thing to have.

Optional Arguments, The Old Way

Previously, we would have to write something like this:

Collapse | Copy Code
public void OldWay()
{
  BarOld(1);
  BarOld(1, 2);
}

public void BarOld(int a)
{
  // 5 being the default value.
  BarOld(a, 5);
}

public void BarOld(int a, int b)
{
  // do something.
}

The syntax available in C# 4.0 is much cleaner.

Generic Covariance and Contravariance

What do these words even mean? From Wikipedia:

  • covariant: converting from wider to smaller (like double to float)
  • contravariant: converting from narrower to wider (like float to double)

First, let’s look at co-contravariance with delegates, which has been around since Visual Studio 2005.

Delegates

Read more.

Not wanting to restate the excellent “read more” example referenced above, I will simply state that covariance allows us to assign a method returning a  sub-class type to the delegate defined as returning a base class type. This is an example of going from something wider (the base class) to something  smaller (the inherited class) in terms of derivation.

Contravariance, with regards to delegates, lets us create a method in which the argument is the base class and the caller is using a sub-class (going from  narrower to wider). For example, I remember being annoyed that I could not consume an event having a MouseEventArgs argument with a generic event handler  having an EventArgs argument. This example of contravariance has been around since VS2005, but it makes for a useful example of the concept.

Generics

Read more.

Also this excellent technical blog on Code Project.

Again, the MSDN page referenced is an excellent read (in my opinion) on co-contravariance with generics. To briefly summarize: as with delegates, covariance allows  a generic return type to be covariant, being able specify a “wide” return type (more general) but able to use a “smaller” (more specialized) return type.  So, for example, the generic interfaces for enumeration support covariance.

Conversely, contravariance lets us go from something narrow (more specialized, a derived class) to something wider (more general, a base class),  and is used as parameters in generic interfaces such as IComparer.

But How Do I Define My Own?

To specify a covariant return parameter, we use the “out” keyword in the generic type. To specify a contravariant method parameter, we use the “in”  keyword in the generic type. For example (read more here):

Collapse | Copy Code
public delegate T2 MyFunc<in T1,out T2>(T1 t1);

T2 is the covariant return type and T1 is the contravariant method parameter.

A further example is here.

Conclusion

In writing this, I was surprised how much I learned that deepened my understanding of C# as well as getting a broader picture of the arc of the  language’s evolution. This was a really useful exercise!

History

Updated the article based on comments received.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

from:http://www.codeproject.com/Articles/327916/C-Language-Features-From-C-2-0-to-4-0#WithoutGenerics3