Auto-Properties
In C# 3.0 and later, auto-implemented properties make property-declaration
more concise when no additional logic is required in the property accessors.
They also enable client code to create objects. When you declare a property as
shown in the following example, the compiler creates a private, anonymous backing
field that can only be accessed through the property's get and set accessors,
just as if you had implemented the property the older, more verbose way.
Example:
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; }
String.IsNullOrWhitespace
The 4.0 framework give us the string.IsNullOrWhitespace() method.
Here's an example where we are concatenating a full name,
and we don't
want a double space if the middle name is empty:
public string GetFullName(string firstName, string middleName, string lastName)
{
if (string.IsNullOrWhiteSpace(middleName))
{
return string.Format("{0} {1}", firstName, lastName);
}
return string.Format("{0} {1} {2}", firstName, middleName, lastName);
}
Another advantage is that IsNullOrWhiteSpace doesn't create any extra string
objects that need to be garbage collected.
The Null Coalescing Operator: ??
The ?? operator is called the null-coalescing operator and is used
to define a default value for a 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. A nullable type can contain a value, or it can be undefined. The
?? operator defines the default value to be returned when a nullable type is
assigned to a non-nullable type. If you try to assign a nullable value type to
a non-nullable value type without using the ?? operator, you will generate a
compile-time error. If you use a cast, and the nullable value type is currently
undefined, an InvalidOperationException exception will be thrown.
An
interesting example would be this:
var myItem = Items.SingleOrDefault(w
=> w.Id == id) ?? GetItemById(id);
The "As" cast
Using the as operator differs from a cast in C# in three important
ways:
It returns null when the variable you are trying to convert
is not of the requested type or in it's inheritance chain, instead of throwing
an exception.
It can only be applied to reference type variables converting
to reference types.
Using as will not perform user-defined conversions,
such as implicit or explicit conversion operators, which casting syntax will
do.
The Stopwatch Class
The Stopwatch class makes it easy to use the high resolution timer
through the convenience of a C# class:
var timer = Stopwatch.StartNew();
SomeCodeToTime();
timer.Stop();
Console.WriteLine("Method took {0} ms", timer.ElapsedMilliseconds);
Timespan static factory methods:
These allow you to construct TimeSpans unambiguously:
TimeSpan.FromDays(double days);
TimeSpan.FromHours(double
hours);
TimeSpan.FromMinutes(double minutes);
TimeSpan.FromSeconds(double seconds);
The using statement
The using statement will call Dispose() on the instance
immediately when scope is left either due to hitting the end of the block or
due to an exception causing the block to leave prematurely
using (var con = new SqlConnection("some connection string"))
using (var cmd = new SqlCommand("select * from orders", con))
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
// ...
}
}
return orders;
}
Object and Collection Initializers:
var startingPoint = new Point() { X = 5, Y = 13 };
var list = new List<int> { 1, 7, 13, 42 };
Implicit Typing with the var keyword.
Implicit typing is not dynamic typing. Any
identifier that is implicitly typed with the keyword var is still strongly typed. The
only difference is that the type is implied from the assignment expression:
var
productsByCategory = new Dictionary<string,List<Product>>();
Extension Methods
Microsoft added the ability to create a static method
in a static class that behaves like it’s a member of the class that it is called
on.
The class you define the extension methods in must be
a static class, and the first parameter of the extension method has the keyword
this in front of its type. This means that this static method will
be invokeable directly from any object of that type:
namespace ExtensionMethods
{
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
Usage:
string s = "Hello Extension Methods";
int i = s.WordCount();
Here's a neat little one:
public static class ObjectExtensions
{
public static string ToXml(this object input)
{
if (input == null) throw new ArgumentNullException("input");
var
xs = new XmlSerializer(input.GetType());
using (var memoryStream = new MemoryStream())
using (var xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding()))
{
xs.Serialize(xmlTextWriter, input);
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
}
}
This
only scratches the surface - there are so many more features, particularly in
the 4.0 Framework, that make programming easier and less error-prone.