Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 8

The correct title of this article is 

C# 4.0. The substitution or omission of a # sign is because of technical restrictions.

C# 4.0 is the latest version of the C# programming language, which was released on April 11, 2010. Microsoft has released the

4.0 runtimeand development environment Visual Studio 2010.[1] The major focus of C# 4.0 is interoperability with partially or fully

dynamically typed languages and frameworks, such as the Dynamic Language Runtime and COM.

Contents

 [hide]

1 Features

o 1.1 Dynamic member lookup

o 1.2 Covariant and contravariant generic

type parameters

o 1.3 Optional ref Keyword when using

COM

o 1.4 Optional parameters and named

arguments

o 1.5 Indexed properties

2 References

3 External links

[edit]Features

The following new features have been added to C# 4.0.[2]

[edit]Dynamic member lookup

A new pseudo-type dynamic is introduced into the C# type system. It is treated as System.Object, but in addition, any

member access (method call, field, property, or indexer access, or a delegate invocation) or application of an operator on a value of

such type is permitted without any type checking, and its resolution is postponed until run-time. This is known as Duck typing.[citation
needed]
 For example:

// Returns the value of Length property or field of any object


int GetLength(dynamic obj)
{
return obj.Length;
}

GetLength("Hello, world"); // a string has a Length property,


GetLength(new int[] { 1, 2, 3 }); // and so does an array,
GetLength(42); // but not an integer - an exception will be thrown here at
run-time
Dynamic method calls are triggered by a value of type "dynamic" as any implicit or explicit parameter (and not just a receiver). For

example:

void Print(dynamic obj)


{
System.Console.WriteLine(obj); // which overload of WriteLine() to call is decided at run-
time
}

Print(123); // ends up calling WriteLine(int)


Print("abc"); // ends up calling WriteLine(string)

Dynamic lookup is performed using three distinct mechanisms: COM IDispatch for COM

objects, IDynamicMetaObjectProvider DLR interface for objects implementing that interface, and reflection for all

other objects. Any C# class can therefore intercept dynamic calls on its instances by

implementing IDynamicMetaObjectProvider.

In case of dynamic method and indexer calls, overload resolution happens at run-time according to the actual types of the values

passed as arguments, but otherwise according to the usual C# overloading resolution rules. Furthermore, in cases where the

receiver in a dynamic call is not itself dynamic, run-time overload resolution will only consider the methods that are exposed on the

declared compile-time type of the receiver. For example:

class Base
{
void Foo(double x);
}

class Derived : Base


{
void Foo(int x);
}

dynamic x = 123;
Base b = new Derived();
b.Foo(x); // picks Base.Foo(double) because b is of type Base, and Derived.Foo(int) is not
exposed
dynamic b1 = b;
b1.Foo(x); // picks Derived.Foo(int)

Any value returned from a dynamic member access is itself of type dynamic. Values of type dynamic are implicitly convertible

both from and to any other type. In the code sample above, this permits GetLength function to treat the value returned by a call

to Length as an integer without any explicit cast. At run-time, the actual value will be converted to the requested type.

[edit]Covariant and contravariant generic type parameters


Generic interfaces and delegates can have their type parameters marked as covariant or contravariant, using

keywords out and in, respectively. These declarations are then respected for type conversions, both implicit and explicit, and

both compile-time and run-time. For example, the existing interface IEnumerable<T> has been redefined as follows:

interface IEnumerable<out T>


{
IEnumerator<T> GetEnumerator();
}

Therefore, any class that implements IEnumerable<Derived> for some class Derived is also considered to be

compatible withIEnumerable<Base> for all classes and interfaces Base that Derived extends, directly, or indirectly. In

practice, it makes it possible to write code such as:

void PrintAll(IEnumerable<object> objects)


{
foreach (object o in objects)
{
System.Console.WriteLine(o);
}
}

IEnumerable<string> strings = new List<string>();


PrintAll(strings); // IEnumerable<string> is implicitly converted to IEnumerable<object>

For contravariance, the existing interface IComparer<T> has been redefined as follows:

public interface IComparer<in T>


{
int Compare(T x, T y);
}

Therefore, any class that implements IComparer<Base> for some class Base is also considered to be compatible

withIComparer<Derived> for all classes and interfaces Derived that are extended from Base. It makes it possible to

write code such as:

IComparer<object> objectComparer = GetComparer();


IComparer<string> stringComparer = objectComparer;
[edit]Optional ref Keyword when using COM

The ref keyword for callers of methods is now optional when calling into methods supplied by COM interfaces. Given a COM method

with the signature

void Increment(ref int x);

the invocation can now be written as either

Increment(0); // no need for "ref" or a place holder variable any more

or
int x = 0;
Increment(ref x);
[edit]Optional parameters and named arguments

C# 4.0 introduces optional parameters with default values as seen in Visual Basic and C++. For example:

void Increment(ref int x, int dx = 1)


{
x += dx;
}

int x = 0;
Increment(ref x); // dx takes the default value of 1
Increment(ref x, 2); // dx takes the value 2

In addition, to complement optional parameters, it is possible to explicitly specify parameter names in method calls, allowing to

selectively pass any given subset of optional parameters for a method. The only restriction is that named parameters must be

placed after the unnamed parameters. Parameter names can be specified for both optional and required parameters, and can be

used to improve readability or arbitrarily reorder arguments in a call. For example:

Stream OpenFile(string name, FileMode mode = FileMode.Open, FileAccess access = FileAccess.Read)


{ ... }

OpenFile("file.txt"); // use default values for both "mode" and "access"


OpenFile("file.txt", mode: FileMode.Create); // use default value for "access"
OpenFile("file.txt", access: FileAccess.Read); // use default value for "mode"
OpenFile(name: "file.txt", access: FileAccess.Read, mode: FileMode.Create); // name all
parameters for extra readability,
// and use order
different from method declaration

Optional parameters make interoperating with COM easier. Previously, C# had to pass in every parameter in the method of the

COM component, even those that are optional. For example:

object fileName = "Test.docx";


object missing = System.Reflection.Missing.Value;

doc.SaveAs(ref fileName,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing);

With support for optional parameters, the code can be shortened as

doc.SaveAs(ref fileName);
Which, due to the now optional ref keyword when using COM, can further be shortened as

doc.SaveAs(fileName);
[edit]Indexed properties

Indexed properties (and default properties) of COM objects are now recognized, but C# objects still do not support them.

The correct title of this article is C# 3.0. The substitution or omission of a # sign is because of technical restrictions.

The programming language C# version 3.0 was released on 19 November 2007 as part of .NET Framework 3.5. It includes new

features inspired by functional programming languages such as Haskell and ML, and is driven largely by the introduction of

the Language Integrated Query (LINQ) pattern to the Common Language Runtime.[1] It is not currently standardized by

any standards organisation.

Contents

 [hide]

1 C# 3.0 Features

o 1.1 LINQ (Language-

Integrated Query)

o 1.2 Object initializers

o 1.3 Collection initializers

o 1.4 Anonymous types

o 1.5 Local variable type

inference

o 1.6 Lambda expressions

o 1.7 Expression trees

o 1.8 Automatic properties

o 1.9 Extension methods

o 1.10 Partial methods

2 References

3 External links

[edit]C# 3.0 Features


[edit]LINQ (Language-Integrated Query)

LINQ is a new Microsoft-specific extensible, general-purpose query language for many kinds of data sources (including plain object

collections, XML documents, databases and so on) which was tightly integrated with other C# language facilities. The syntax is

different from, but borrows from SQL. An example:

int[] array = { 1, 5, 2, 10, 7 };


// Select squares of all odd numbers in the array sorted in descending order
IEnumerable<int> query = from x in array
where x % 2 == 1
orderby x descending
select x * x;
// Result: 49, 25, 1

In order to implement LINQ, a large range of new methods were added to many collections via

the System.Linq.Enumerable class. LINQ query language expressions are translated to use these functions before

compilation. As an alternative, which is sometimes more powerful or direct, these functions may be accessed directly.[2] Doing so

makes more use of lambda functions, which are discussed below. The following is functionally identical to the example above.

IEnumerable<int> query = array.Where(x => x % 2 == 1).OrderByDescending(x => x).Select(x => x *


x);
// Result: 49, 25, 1 using 'array' as defined in previous example
[edit]Object initializers
Customer c = new Customer();
c.Name = "John";

can be written

Customer c = new Customer { Name = "John" };


[edit]Collection initializers
MyList list = new MyList();
list.Add(1);
list.Add(2);

can be written as

MyList list = new MyList { 1, 2 };

assuming that MyList implements System.Collections.IEnumerable and has a public Add method. [3]

[edit]Anonymous types

Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to first

explicitly define a type. The type name is generated by the compiler and is not available at the source code level. The type of the

properties is inferred by the compiler.

var x = new { FirstName = "John", LastName = "Doe" };

Anonymous types are reference types that derive directly from object. The compiler gives them a name although your application

cannot access it. From the perspective of the common language runtime, an anonymous type is no different from any other

reference type, except that it cannot be cast to any type except for object.

If two or more anonymous types have the same number and type of properties in the same order, the compiler treats them as the

same type and they share the same compiler-generated type information. [4]

[edit]Local variable type inference


Local variable type inference:

var x = new Dictionary<string, List<float>>();

is interchangeable with

Dictionary<string, List<float>> x = new Dictionary<string, List<float>>();

This feature is not just a convenient syntactic sugar for shorter local variable declarations, but it is also required for the declaration of

variables of anonymous types. The contextual keyword "var", however, may only appear within a local variable declaration.

[edit]Lambda expressions

Lambda expressions provide a concise way to write first-class anonymous function values. Compare the following C# 2.0 snippet:

listOfFoo.Where(delegate(Foo x) { return x.Size > 10; })

with this C# 3.0 equivalent:

listOfFoo.Where(x => x.Size > 10);

In the above examples, lambda expressions are merely short-hand syntax for anonymous delegates with type inference for

parameters and return type. However, depending on the context they are used in, a C# compiler can also transform lambdas

into ASTs that can then be processed at run-time. In the example above, if listOfFoo is not a plain in-memory collection, but a

wrapper around a database table, it could use this technique to translate the body of the lambda into the equivalent SQL expression

for optimized execution. Either way, the lambda expression itself looks exactly the same in the code, so the way it is used at run-

time is transparent to the client.

[edit]Expression trees

Expressions, such as x <= y, a = b + c, or even lambda functions and other complex forms can be created dynamically
usingexpression trees. Much of the functionality is provided by static methods of the

class System.Linq.Expressions.Expression. There are also various new classes in that namespace that

represent the expressions and partial expressions created by those methods as software objects. These

include BinaryExpression, which could represent x <= y; LambdaExpression and many others. When


combined with aspects of the reflection API, this can be a very powerful tool, if a little challenging to write and debug.[5][6]

[edit]Automatic properties

The compiler will generate a private instance variable and the appropriate accessor and mutator given code such as:

public string Name { get; private set; }


[edit]Extension methods

Extension methods are a form of syntactic sugar providing the illusion of adding new methods to the existing class outside its

definition. In practice, an extension method is a static method that is callable as if it was an instance method; the receiver of the call

is bound to the first parameter of the method, decorated with keyword this:

Extension methods allow developers to add new methods to the public contract of an existing CLR type, without having to sub-class

it or recompile the original type.


1. All Extension Methods need to be defined in a static class.

2. All Extension Methods need to be defined as a static method.

3. All Extension Methods need to take at least one parameter defined as follows:

this (keyword) string (type) parameterName


Where the type is whatever type that you wish to extend.

4. The this parameter needs to be the first parameter. All other parameters are optional—and must follow this.

public static class StringExtensions


{
public static string Left(this string s, int n)
{
return s.Substring(0, n);
}
}

string s = "foo";
s.Left(3); // same as StringExtensions.Left(s, 3);
[edit]Partial methods

Partial methods allow code generators to generate method declarations as extension points that are only included in the compilation

if someone actually implements them in another portion of a partial class.[7]

You might also like