C# 4.0 is a version of the C# programming language that was released on April 11, 2010.
Microsoft
Microsoft Corporation is an American multinational technology corporation producing computer software, consumer electronics, personal computers, and related services headquartered at the Microsoft Redmond campus located in Redmond, Washin ...
released the 4.0 runtime and development environment
Visual Studio 2010
Visual Studio is an integrated development environment (IDE) from Microsoft. It is used to develop computer programs including web site, websites, web apps, web services and mobile apps. Visual Studio uses Microsoft software development platfor ...
. The major focus of C# 4.0 is interoperability with partially or fully dynamically typed languages and frameworks, such as the
Dynamic Language Runtime
The Dynamic Language Runtime (DLR) from Microsoft runs on top of the Common Language Runtime (CLR) and provides computer language services for dynamic languages. These services include:
* A dynamic type system, to be shared by all languages using ...
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
Duck typing in computer programming is an application of the duck test—"If it walks like a duck and it quacks like a duck, then it must be a duck"—to determine whether an object can be used for a particular purpose. With nominative ty ...
. For example:
// Returns the value of Length property or field of any object
int GetLength(dynamic obj)
GetLength("Hello, world"); // a string has a Length property,
GetLength(new int[] ); // and so does an array,
GetLength(42); // but not an integer - an exception will be thrown in GetLength method 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)
Print(123); // ends up calling WriteLine(int)
Print("abc"); // ends up calling WriteLine(string)
Dynamic lookup is performed using three distinct mechanisms: COM
IDispatch
IDispatch is the interface that exposes the OLE Automation protocol. Extending IUnknown, it is one of the standard interfaces that can be exposed by COM objects. COM distinguishes between three interface types: ''custom'' that are VTABLE-based I ...
for COM objects, IDynamicMetaObjectProvider DLR interface for objects implementing that interface, and
reflection Reflection or reflexion may refer to:
Science and technology
* Reflection (physics), a common wave phenomenon
** Specular reflection, reflection from a smooth surface
*** Mirror image, a reflection in a mirror or in water
** Signal reflection, in ...
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
class Derived : Base
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.
Covariant and contravariant generic type parameters
Generic
Generic or generics may refer to:
In business
* Generic term, a common name used for a range or class of similar things not protected by trademark
* Generic brand, a brand for a product that does not have an associated brand or trademark, other ...
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 has been redefined as follows:
interface IEnumerable
Therefore, any class that implements IEnumerable for some class Derived is also considered to be compatible with IEnumerable 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
For contravariance, the existing interface IComparer has been redefined as follows:
public interface IComparer
Therefore, any class that implements IComparer for some class Base is also considered to be compatible with IComparer for all classes and interfaces Derived that are extended from Base. It makes it possible to write code such as:
IComparer objectComparer = GetComparer();
IComparer stringComparer = objectComparer;
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);
Optional parameters and named arguments
C# 4.0 introduces optional parameters with default values as seen in
Visual Basic Visual Basic is a name for a family of programming languages from Microsoft. It may refer to:
* Visual Basic .NET (now simply referred to as "Visual Basic"), the current version of Visual Basic launched in 2002 which runs on .NET
* Visual Basic ( ...
and
C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
. For example:
void Increment(ref int x, int dx = 1)
int x = 0;
Increment(ref x); // dx takes the default value of 1, after the method returns x 1
Increment(ref x, 2); // dx takes the value 2, after the method returns x 3
In addition, to complement optional parameters, it is possible explicitly to specify parameter names in method calls, allowing the programmer selectively to pass any subset of optional parameters for a method. The only restriction is that
named parameter
In computer programming, named parameters, named argument or keyword arguments refer to a computer language's support for function calls that clearly state the name of each parameter within the function call.
Overview
A function call using na ...
s 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 to 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);
Indexed properties
Indexed properties (and default properties) of COM objects are now recognized, but C# objects still do not support them.