C Sharp 2.0#Null-coalescing operator
{{short description|Version of the C# programming language}}
{{Correct title|title=C# 2.0|reason=hash}}
The computer programming language, C#, introduces several new features in version 2.0 (corresponding to the 3rd edition of the ECMA-334 standard and the .NET Framework 2.0). These include:
C# 2.0 Features
= Partial class =
Partial classes allow implementation of a class to be spread between several files, with each file containing one or more class members. It is useful primarily when parts of a class are generated automatically. For example, the feature is heavily used by code-generating user interface designers in Visual Studio.
file1.cs:
public partial class MyClass
{
public void MyMethod1()
{
// Manually written code
}
}
file2.cs:
public partial class MyClass
{
public void MyMethod2()
{
// Automatically generated code
}
}
= Generics =
Generics, or parameterized types, or parametric polymorphism is a .NET 2.0 feature supported by C# and Visual Basic. Unlike C++ templates, .NET parameterized types are instantiated at runtime rather than by the compiler; hence they can be cross-language whereas C++ templates cannot. They support some features not supported directly by C++ templates such as type constraints on generic parameters by use of interfaces. On the other hand, C# does not support non-type generic parameters. Unlike generics in Java, .NET generics use reification to make parameterized types first-class objects in the CLI Virtual Machine, which allows for optimizations and preservation of the type information.{{cite web
|url=http://msdn.microsoft.com/en-us/library/ms379564.aspx
|title=An Introduction to C# Generics
|date=January 2005
|publisher=Microsoft
|access-date=June 18, 2009
}}
= Static classes =
Static classes are classes that cannot be instantiated or inherited from, and that only allow static members. Their purpose is similar to that of modules in many procedural languages.
= Generator functionality =
The .NET 2.0 Framework allowed C# to introduce an iterator that provides generator functionality, using a yield return
construct similar to yield
in Python.{{cite web
|url=http://msdn.microsoft.com/en-us/library/9k7k7cf0(VS.80).aspx
|title=yield
|work=C# Language Reference
|publisher=Microsoft
|access-date=2009-04-26}} With a yield return
, the function automatically keeps its state during the iteration.
// Method that takes an iterable input (possibly an array)
// and returns all even numbers.
public static IEnumerable
{
foreach (int i in numbers)
{
if (i % 2 == 0)
yield return i;
}
}
There is also a yield break
statement, in which control is unconditionally returned to the caller of the iterator. There is an implicit yield break
at the end of each generator method.
= Anonymous delegates =
As a precursor to the lambda functions introduced in C# 3.0, C#2.0 added anonymous delegates. These provide closure-like functionality to C#.{{cite web
|url=http://msdn.microsoft.com/en-us/library/0yw3tz5k(VS.80).aspx
|title=Anonymous Methods (C#)
|work=C# Programming Guide
|publisher=Microsoft
|access-date=June 18, 2009
}} Code inside the body of an anonymous delegate has full read/write access to local variables, method parameters, and class members in scope of the delegate, excepting out
and ref
parameters. For example:-
int SumOfArrayElements(int[] array)
{
int sum = 0;
Array.ForEach(array,
delegate(int x)
{
sum += x;
}
);
return sum;
}
Unlike some closure implementations, each anonymous delegate instance has access to the same relative memory location for each bound variable, rather than to the actual values at each creation. See a fuller discussion of this distinction.
= Delegate covariance and contravariance =
Conversions from method groups to delegate types are covariant and contravariant in return and parameter types, respectively.{{cite web
|url=http://msdn.microsoft.com/en-us/library/ms173174(VS.80).aspx
|title=Covariance and Contravariance in Delegates (C#)
|work=C# Programming Guide
|publisher=Microsoft
|access-date=June 18, 2009
}}
= The accessibility of property accessors can be set independently =
Example:
string status = string.Empty;
public string Status
{
get { return status; } // anyone can get value of this property,
protected set { status = value; } // but only derived classes can change it
}
= Nullable value types =
Nullable value types (denoted by a question mark, e.g. int? i = null;
) which add null
to the set of allowed values for any value type. This provides improved interaction with SQL databases, which can have nullable columns of types corresponding to C# primitive types: an SQL INTEGER NULL
column type directly translates to the C# int?
.
Nullable value types received an improvement at the end of August 2005, shortly before the official launch, to improve their boxing characteristics: a nullable variable which is assigned null is not actually a null reference, but rather an instance of struct Nullable
with property HasValue
equal to false
. When boxed, the Nullable
instance itself is boxed, and not the value stored in it, so the resulting reference would always be non-null, even for null values. The following code illustrates the corrected flaw:
int? i = null;
object o = i;
if (o == null)
System.Console.WriteLine("Correct behaviour - runtime version from September 2005 or later");
else
System.Console.WriteLine("Incorrect behaviour - pre-release runtime (from before September 2005)");
When copied into objects, the official release boxes values from Nullable
instances, so null values and null references are considered equal. The late nature of this fix caused some controversy{{cite web
|url=http://blogs.msdn.com/somasegar/archive/2005/08/11/450640.aspx
|title=Nulls not missing anymore
|author=Somasegar
|date=August 11, 2005
|access-date=2008-11-05
|work=Somasegar's WebLog
|publisher=MSDN
}}
, since it required core-CLR changes affecting not only .NET2, but all dependent technologies (including C#, VB, SQL Server 2005 and Visual Studio 2005).
= Null-coalescing operator =
The ??
operator is called the null coalescing operator and is used to define a default value for nullable value types as well as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand.{{cite web
|url=http://msdn.microsoft.com/en-us/library/ms173224.aspx
|title=?? Operator
|work=C# Reference
|publisher=Microsoft
|access-date=2008-11-23
}}
object nullObj = null;
object obj = new Object();
return nullObj ?? obj; // returns obj
The primary use of this operator is to assign a nullable type to a non-nullable type with an easy syntax:
int? i = null;
int j = i ?? 0; // If i is not null, initialize j to i. Else (if i is null), initialize j to 0.