practises and performance c# (tektak).docx.pdf

26
Performance 1. Choose data type before using it There is great impact if we choose wrong data type. I will show one demonstration to prove this concept. public static class DataTypeTest { public static void Call() { List<int> list = new List<int>(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 20000; i++) { list.Add(i); } stopwatch.Stop(); Console.Write("Using Arraylist(Object)" + stopwatch.ElapsedTicks + "\n"); stopwatch.Reset(); stopwatch.Start(); int[] a = new int[20000]; for (int i = 0; i < 20000; i++) { a[i] = i; } stopwatch.Stop(); Console.Write("Using Value(Integer Array)" + stopwatch.ElapsedTicks); Console.ReadLine(); } } Above code has 2 cases one using generic List another using integer array to store 20000 integer values. The respective screenshot is also shown. So second case of integer array is faster.

Upload: anthony-harrell

Post on 25-Dec-2015

227 views

Category:

Documents


2 download

TRANSCRIPT

Performance 1. Choose data type before using it

There is great impact if we choose wrong data type. I will show one demonstration to prove

this concept.

public static class DataTypeTest { public static void Call() { List<int> list = new List<int>(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 20000; i++) { list.Add(i); } stopwatch.Stop(); Console.Write("Using Arraylist(Object)" + stopwatch.ElapsedTicks + "\n"); stopwatch.Reset(); stopwatch.Start(); int[] a = new int[20000]; for (int i = 0; i < 20000; i++) { a[i] = i; } stopwatch.Stop(); Console.Write("Using Value(Integer Array)" + stopwatch.ElapsedTicks); Console.ReadLine(); } }

Above code has 2 cases one using generic List another using integer array to store 20000

integer values. The respective screenshot is also shown. So second case of integer array is

faster.

Before going on to the above case lets know about boxing and unboxing. For variables that are

based on value types have value directly and those of reference types also known as objects

store references to original data. Whenever these objects are to be used boxing occurs i.e first

allocation of object instance is done in the heap and secondly copy is made for use depending

upon application behavior. Boxing is the packaging of the value type in an instance of the object

reference type and unboxing is the extraction of the value type from the reference type. In

above case boxing and unboxing occurs to list but not to array.

Where possible use arrays instead of List (collections). Arrays are normally more efficient

especially for value types. Also, initialize collections to their required size when possible.

Initializing the list to fixed size also improve performance since memory allocation for any

collection data is first 0 then 4 then 16 and so on if not specified that takes time if it has to be

done at runtime. Hence, if you initialize collection once memory is allocated and performance

increases.

2. Replace ArrayList with List<>

ArrayList are useful when storing multiple types of objects within the same list. However if you are keeping the same type of variables in one ArrayList, you can gain a performance boost by using List<> objects instead.

public static class ListArrayListTest { public static void Call() { ArrayList intArrayList = new ArrayList(); List<int> intList = new List<int>(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 1000; i++) { intArrayList.Add(10); } stopwatch.Stop(); Console.WriteLine("Using Arraylist: " + stopwatch.ElapsedTicks); stopwatch.Restart(); for (int i = 0; i < 1000; i++) { intList.Add(10); } stopwatch.Stop();

Console.WriteLine("Using List<>: " + stopwatch.ElapsedTicks); Console.ReadLine(); } }

Notice above case only contains intergers. Using the List<> class is a lot better. To convert it to a typed List, only the variable types need to be changed:

There is no need to cast types with List<>. The performance increase can be especially significant with primitive data types like integers.

3. Smart Try-Catch

Try-Catch statements are meant to catch exceptions that are beyond the programmers control. Using a try statement to keep code "simple" instead of using if statements to avoid error-prone calls makes code incredibly slower. Restructure your source code to require less try statements.

public static class SmartTryCatch { public static void Call() { string myString="My String"; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { int length = myString.Length; } catch (Exception) { } stopwatch.Stop(); Console.WriteLine("Using try catch: " + stopwatch.ElapsedTicks);

stopwatch.Restart(); if (myString != null) { int length = myString.Length; } stopwatch.Stop(); Console.WriteLine("Without Using try catch: " + stopwatch.ElapsedTicks); Console.ReadLine(); } }

4. Replace Divisions

C# is relatively slow when it comes to division operations. So it is better to use multiplication

shift. There are different ways to find multiplication shift. This link describes more in shift

operations.

5. Use For loop instead of Foreach

We are more familiar to foreach loop these days than for. Demo below clears your idea on it

what to use for best results.

public static class ForForeachTest { public static void Call() { List<int> Count = new List<int>(); List<int> list1 = new List<int>(); List<int> list2 = new List<int>(); for (int i = 0; i < 20000; i++)

{ Count.Add(i); } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < Count.Count; i++) { list1.Add(i); } stopwatch.Stop(); Console.Write("For Loop :- " + stopwatch.ElapsedTicks + "\n"); stopwatch.Restart(); foreach (int a in Count) { list2.Add(a); } stopwatch.Stop(); Console.Write("Foreach Loop:- " + stopwatch.ElapsedTicks); Console.ReadLine(); } }

From the output it is clear that For loop is better.

6. Choose when to use a class and when to use a structure

struct MyStructure { public string Name; public string Surname; } class MyClass {

public string Name; public string Surname; } public static class ClassStructTest { public static void Call() { MyStructure[] structureObject = new MyStructure[2000]; MyClass[] classObject = new MyClass[2000]; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 2000; i++) { structureObject[i] = new MyStructure(); structureObject[i].Name = "Harris"; structureObject[i].Surname = "Sapkota"; } stopwatch.Stop(); Console.WriteLine("For Structure:- " + stopwatch.ElapsedTicks); stopwatch.Restart(); for (int i = 0; i < 2000; i++) { classObject[i] = new MyClass(); classObject[i].Name = "Harris"; classObject[i].Surname = "Sapkota"; } stopwatch.Stop(); Console.WriteLine("For Class:- " + stopwatch.ElapsedTicks); Console.ReadLine(); } }

As see we found that structure are loads faster in term of object storage.

The reason is, structure variables are value types and in one location the value (or structure

variable) is stored. In case of class, a class object is a reference type. For object type the

reference is created and the value is stored in some other location of memory. Basically the

value is stored in a manageable heap and the pointer is created in the stack. And to implement

an object in memory in this fashion, generally it will take more time than a structure variable.

7. Always use Stringbuilder for String concatenation operations

It seems confusing in choosing between string and string builder. The below demo let you clear

your ideas for that confusion.

public static class StringBuilderTest { public static void Call() { string First = "A"; string Second = "Affff"; StringBuilder stringBuilder = new StringBuilder("A"); StringBuilder stringBuilder2 = new StringBuilder("Affff"); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 1000; i++) { First = First + "A"; } stopwatch.Stop(); Console.WriteLine("Case 1"); Console.WriteLine("Using String :-" + stopwatch.ElapsedTicks); stopwatch.Restart(); for (int i = 0; i < 1000; i++) { stringBuilder.Append("A"); } stopwatch.Stop(); Console.WriteLine("Using Stringbuilder :-" + stopwatch.ElapsedTicks); stopwatch.Restart(); Second = Second + "Baaaaaa"; Second = Second + "Cssssss"; Second = Second + "Ddddddd"; Second = Second + "Baaaaaa"; Second = Second + "Cssssss"; Second = Second + "Ddddddd";

Second = Second + "Baaaaaa"; Second = Second + "Cssssss"; Second = Second + "Ddddddd"; Second = Second + "Baaaaaa"; Second = Second + "Cssssss"; Second = Second + "Ddddddd"; stopwatch.Stop(); Console.WriteLine("Case 2"); Console.WriteLine("Using String :-" + stopwatch.ElapsedTicks); stopwatch.Restart(); stringBuilder.Append("Baaaaaa"); stringBuilder.Append("Cssssss"); stringBuilder.Append("Ddddddd"); stringBuilder.Append("Baaaaaa"); stringBuilder.Append("Cssssss"); stringBuilder.Append("Ddddddd"); stringBuilder.Append("Baaaaaa"); stringBuilder.Append("Cssssss"); stringBuilder.Append("Ddddddd"); stringBuilder.Append("Baaaaaa"); stringBuilder.Append("Cssssss"); stringBuilder.Append("Ddddddd"); stringBuilder.Append("Baaaaaa"); stringBuilder.Append("Cssssss"); stringBuilder.Append("Ddddddd"); stopwatch.Stop(); Console.WriteLine("Using Stringbuilder :-" + stopwatch.ElapsedTicks); Console.ReadLine(); } }

In C# a string is immutable and cannot be altered. When you alter a string, you are actually

creating a new string, which in turn uses more memory than necessary, creates more work for

the garbage collector and makes the code execution run slower. When a string is being

modified frequently it begins to be a burden on performance. If you just want to append

something to a string a single time then a StringBuilder class is overkill. A simple string type

variable in this case improves on resources use and readability of the C# source code.

StringBuilder is a string-like object whose value is a mutable sequence of characters. The value is said to be mutable because it can be modified once it has been created by appending, removing, replacing, or inserting characters. The thing is StringBuilder is faster mostly with big strings. This means if you have a loop that will add to a single string for many iterations then a StringBuilder class is definitely much faster than a string type.

In general, use Stringbuilder if more than four concatenations are required.

8. Using Statement

Freeing memory is equally important as allocating memory for our application. There are Garbage Collectors (GC) in C# that care of memory cleanup yet some classes in the .NET library implement the IDisposable interface, and these require manual object disposal. In the code-snippet below, we make a new instance of the SHA1 class, and in the finally code-block we dispose the object.

SHA1 sha1 = SHA1.Create(); try { StringBuilder sb = new StringBuilder(); byte[] data = Encoding.UTF8.GetBytes("text"); byte[] hash = sha1.ComputeHash(data); foreach (byte b in hash) { sb.Append(b.ToString("x2").ToLower()); } var hashed = sb.ToString(); } finally { if (sha1 != null) ((IDisposable)sha1).Dispose(); }

The above code can be further improved by removing try catch and finally which degrade performance. A better way is to use the using statement once, as shown below:

// Allocate using (System.Security.Cryptography.SHA1 sha1 = System.Security.Cryptography.SHA1.Create()) { //Use the sha1 to computer the hash. //sha1 can only be used inside this code-block } //Automatically Disposed

In the second code-snippet, using (...) { ... } will only allow the usage of an object once within the curly braces ("{}"), and disposal will happen automatically after the last curly brace. This approach is much better, especially, if we only need to use one class once.

9. Choose best way to assign class data member

We should look carefully while assigning value to class data member. The demo clears more.

public class Test { public static string Name { get; set; } public static String surname; } public static class AssignMemberValueClassTest { public static void Call() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 100; i++) { Test.Name = "Value"; } stopwatch.Stop(); Console.WriteLine("Using Property: " + stopwatch.ElapsedTicks); stopwatch.Restart(); for (int i = 0; i < 100; i++) { Test.surname = "Value"; } stopwatch.Stop(); Console.WriteLine("Direct Assign: " + stopwatch.ElapsedTicks); Console.ReadLine();

} }

Using the property methods are always slow.

10. Comparing Non-Case-Sensitive Strings

In an application sometimes it is necessary to compare two string variables, ignoring the cases. The tempting and traditionally approach is to convert both strings to all lower case or all upper case and then compare them.

However repetitively calling the function ToLower() is a bottleneck in performace. By instead using the built-in string.Compare() function you can increase the speed of your applications.

The C# string.Compare function returns an integer that is equal to 0 when the two strings are equal.

public static class NonCaseCompareString { public static void Call() { string firstString = "Harris"; string secondString = "harris"; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 100; i++) { bool valid = firstString.ToLower() == secondString.ToLower(); Test.Name = "Value"; } stopwatch.Stop(); Console.WriteLine("Using ToLower: " + stopwatch.ElapsedTicks); stopwatch.Restart(); for (int i = 0; i < 100; i++) {

bool valid = string.Compare(firstString, secondString, true)==0; } stopwatch.Stop(); Console.WriteLine("Using String Compare: " + stopwatch.ElapsedTicks); Console.ReadLine(); } }

11. Read Values From Objects Only Once

Reading values from objects is not as fast as assessing the value of a simple variable. For example, a loop through an array’s contents should not access the array’s Length property on each iteration of the loop, instead copy the Length property to an Integer and then access this value on each iteration.

This applies to any classes you create as well, read all properties into a simple string or integer type if possible and then access that type multiple times.

12. Use Sealed Classes

Classes that do not need to be inherited from should be marked as sealed. Sealed classed remove the inheritance features of a class and allows the .NET framework to make several run-time optimizations

13. Consider Overriding the Equals Method for Value Types

You can override the Equals method for value types to improve performance of the Equals method. The Equals method is provided by System.Object. To use the standard implementation of Equals, your value type must be boxed and passed as an instance of the reference type System.ValueType. The Equals method then uses reflection to perform the comparison. However, the overhead associated with the conversions and reflections can easily be greater than the cost of the actual comparison that needs to be performed. As a result, an Equals method that is specific to your value type can do the required comparison significantly more cheaply. The following code fragment shows an overridden Equals method implementation that improves performance by avoiding reflection costs.

public struct Rectangle { public double Length; public double Breadth; public override bool Equals(object ob) { if (ob is Rectangle) return Equals((Rectangle)ob); else return false; } private bool Equals(Rectangle rect) { return this.Length == rect.Length && this.Breadth == rect.Breadth; } }

14. Asynchronous Programming with Async and Await in C# 5.0

Asynchronous and Synchronous programming has always been useful, especially when we want our application to be able to perform multiple operations at the same time i.e. multitasking. However, the traditional way of writing asynchronous applications is usually complicated, resulting in applications that become difficult to—write, debug, and maintain.

The traditional way

public delegate int GetValueAsync(int callDuration); class ProgramA { public ProgramA() { }

public int GetValueMethod(int callDuration) { Thread.Sleep(callDuration); int i = ReturnRandomNumber(); return i; } private int ReturnRandomNumber() { return new Random().Next(1, 1000); } }

C# 5.0 introduces two new keywords, async and await—these help C# developers build asynchronous applications that are capable of achieving multitasking without performance issues.

The New Modern way

class ProgramB { public ProgramB() { } public async void PrintAsync() { int a = await GetValueAsync(); Console.WriteLine("The Multiplication of one" + " random number with itself is: {0}", a * a); } private async Task<int> GetValueAsync() { int i = ReturnRandomNumber(); return await Task.FromResult<int>(i); } private int ReturnRandomNumber() { return new Random().Next(1, 1000); } }

Create and initialize one instance of each, and then invoke their methods:

static void Main(string[] args) { ProgramA prgm = new ProgramA(); GetValueAsync gasync = new GetValueAsync(prgm.GetValueMethod); IAsyncResult result = gasync.BeginInvoke(2000, null, null); Console.WriteLine("Test method GetValueAsync() from ProgramA begins."); Thread.Sleep(300); int a = gasync.EndInvoke(result);

Console.WriteLine("The Multiplication of one random numbers is: {0}", a * a); Console.WriteLine("\n\n"); ProgramB prgmB = new ProgramB(); Console.WriteLine("Test method PrintAsync() from ProgramB begins.\n"); prgmB.PrintAsync(); Console.WriteLine("\n"); Console.ReadKey(); }

In conclusion, we can easily avoid performance bottlenecks and enhance the overall responsiveness of our C# applications by using asynchronous programming. The new Visual Studio and .NET Framework leverages asynchronous support via a simplified approach, async programming. In Windows 8 the support for asynchronous programming is much more extended thanks to the Windows Runtime (WinRT).

Productivity 1. Use string.Empty

This is not so much a performance improvement as it is a readability improvement, but it still counts as code optimization. Try to replace lines like:

if (str == "")

with:

if (str == string.Empty)

This is simply better programming practice and has no negative impact on performance.

Note, there is a popular practice that checking a string's length to be 0 is faster than comparing it to an empty string. While that might have been true once it is no longer a significant performance improvement. Instead stick with string.Empty.

2. Use && and || operators

When building if statements, simply make sure to use the double-and notation (&&) and/or the double-or notation (||).If statements that use & and | must check every part of the statement and then apply the "and" or "or". On the other hand, && and || go through the statements one at a time and stop as soon as the condition has either been met or not met.

Executing less code is always a performace benefit but it also can avoid run-time errors, consider the following C# code:

if (object1 != null && object1.runMethod())

If object1 is null, with the && operator, object1.runMethod()will not execute. If the && operator is replaced with &, object1.runMethod() will run even if object1 is already known to be null, causing an exception.

3. ‘as’ Vs type casting

As good programming practice we try to avoid coercing one type into another when we can. But sometimes, runtime checking is simply unavoidable. When you have to cast an object into another type you have a couple of choices: the as operator or casting. You should use the as operator whenever you can because it is safer and more efficient at runtime. Using traditional casting you could write something like the following.

object o = new MyObject(); try { MyType m; m = (MyType)o; if (m != null) { //work with m as a MyType object } else { //Report null reference failure } } catch { //report the conversion failure }

Instead we will use the as operator as an alternative and produce simpler and easier to read code.

object o = new MyObject(); MyType m = o as MyType; if (m != null)

The as operator is similar to a cast operation; however, there are two advantages to using the as operator.

It makes your code more readable. If a type mismatch occurs, the object will become null instead of throwing an

exception. Note: Using the as operator instead of casting only works for reference types.

4. Control overflow checking

Each numerical data type has a fixed upper and lower limit. When you are performing arithmetic operations on a specific type, it is very possible that you may accidentally overflow the maximum storage of the type, or underflow the minimum storage of the type (collectively referred to as overflow). Overflow checking may seem somewhat unimportant since it will not occur often. Of course, even if you don't expect an overflow condition, it may still occur as a result of a bug. You can turn on overflow checking in your Visual Studio project but there is a performance penalty associated with overflow checking. You may not want to slow down your code with overflow checking if you are sure that overflow can never occur or that you will handle the specific examples where it may occur. It is recommended that in debug builds you can turn on overflow checking to help spot bugs and isolate issues during your testing. In the release build, turn off overflow checking. Checked and unchecked specify whether arithmetic operations and conversions are checked for overflow. These two keywords are prefix keywords. They can apply to an expression, a statement, or a block of statements. A checked expression is one that will throw an exception if overflow occurs during evaluation. An unchecked expression is one that will not throw an exception. The keywords “checked” and “unchecked” can be used to explicitly specify how the evaluation is to be done. int j = checked(a * b); int k = unchecked(a * b);

First, a checked expression only works for arithmetic which results in an integer type. Another thing to watch is that the checked/unchecked keywords have no effect when division by zero is attempted - a DivideByZeroException is always thrown. Another issue is that overflow checking works for simple arithmetic operations (addition, subtraction, and multiplication), but no overflow checking is performed on left shift operations.

The unchecked keyword suppresses overflow checking and does not raise any

OverflowException. If any operation results in an overflow while using unchecked, its value is

truncated and the result is returned. You should use the checked keyword when you know an

overflow may occur and you want to handle the error.

5. Using readonly versus const

There are two different versions of constants in C#: the const keyword is used for compile-time constants and the readonly keyword is used for runtime constants.

A mistake that developers may make is the use of const when readonly would be more appropriate. The main issue with const is that it's evaluated at compile-time, which means if it's changed at a later date, you have to not only recompile that application, but all applications that reference that application. In constrast, readonly is evaluated at run-time providing you a lot more flexibility.

Here’s an overview of the differences between const and readonly in C#.

Const Readonly

Can not be static. Can be either instance-level or static.

The value is evaluated at compile time. The value is evaluated at run time.

It is initialized at declaration only. It can be initialized in declaration or by code in the constructor. Therefore, readonly fields can have different values depending on the constructor used.1

So, const should really only be used for logical, real-world constants such as days of the week, numerical constants, etc. As far as performance goes, you actually lose a little performance using readonly, but you make up for it in the flexibility of your application.

6. Ternary Operator (?:)

string IsEligibleToPurchaseAlcohol(int age) { string message = null; if (age >= 21) { message = "Congratulations! You are eligible to buy alcohol."; } else { message = "Sorry! You're not eligible to buy alcohol."; } return message; }

string IsEligibleToPurchaseAlcohol(int age) { return age >= 21 ? "Congratulations! You are eligible to buy alcohol." : "Sorry! You're not eligible to buy alcohol."; }

Here it is shown how few lines of coding could save our time by such reduction.

7. Null-Coalesce Operator (??)

In general we may write code as:

object a = null; object b = new object(); object c; if (a != null) c = a; else c = b;

It is very obvious that a C# developer that has just learned to use the ternary operator will rewrite this to a single line.

object a = null; object b = new object(); object c = a ?? b;

With the null-coalescing operator we can make this shorter. If the left-hand side equals null, the right-hand side will be assigned, in this context object b.

8. Boolean

if (IndividualsNormalAge() == true) { System.Diagnostics.Debug.Print("Yes!"); } else { System.Diagnostics.Debug.Print("No!"); }

To make this more efficient, simply remove == true, and it will be determined autormatically.

if (IndividualsNormalAge()) { System.Diagnostics.Debug.Print("Yes!"); } else { System.Diagnostics.Debug.Print("No!"); } bool IndividualsNormalAge() { Random r = new Random(); int age = r.Next(1, 113); return (age < 111) ? true : false; }

The ? true : false can be removed, and it will still return true/false.

bool IndividualsNormalAge() { Random r = new Random(); int age = r.Next(1, 113); return (age < 111); }

9. Is String Null?

The string.IsNullOrEmpty tests strings by checking for string references that are null, or empty strings. In short, the static method IsNullOrEmpty enables you to simultaneously test whether a String is null or its value is Empty—as tested in the code-snippet below:

if (string.IsNullOrEmpty(s)) return "This string is null or empty."; else return string.Format("This string is not null or empty, it equals to \"{0}\" ", s);

10. Data Type Conversion

It's very common that we sometimes or very often have to convert data types for various of reasons, for instance, if the we have a decimal variable with a set value, and we want to convert it into an Integer or int an explicit conversion will be performed to achieve this.

int j = 0; decimal money = 9500.34m;

j = (int)money; // An explicit conversion using cast operator.

The better option is to use the Convert class which supports full Data Type conversion between all data types.

int money = 0; string uservalue = null; uservalue = Console.ReadLine(); money = Convert.ToInt32(uservalue);

In the first code-snippet we do explicit conversion using a cast operator, and in the second code-snippet we use the Convert class and invoke the ToInt32() method to convert a string to an int. Is there any difference? Yes, of course there's a difference between the first code-snippet and the second code-snippet—I'll explain, explicit conversions strictly requires a cast operator, and that the source and destination variables are compatible. Conversion using a helper class such as Convert allows us to convert between non-compatible types and does not require the use of cast operator, thus, providing a safe conversion method with performance benefits.

11. Properties

Prior to C# 2.0, programmers used to solve things very differently, see the first code-snippet:

class Child { public Child() { } private int age = 0; public int GetAge() { return age; } public void SetAge(int _age) { age = _age; } }

In the first code-snippet, a programmer in C# 1.0 was required to write two methods to be able to set and get a value, in this context, the age of a child. However, that's a lot of code, and it quickly gets messy and it's not elegant enough. However, this issue was solved in C# 2.0 with the introduction of Properties. The code-snippet below demonstrates Properties.

class Child { public Child() { } private int _age = 0;

public int Age { get { return _age; } set { _age = value; } } }

The Properties are really useful, especially when we need to protect internal variables and not expose them to the outside world. The second code-snippet above clearly protects our internal variable, _age. However, even the second code-snippet isn't elegant enough, what's elegant is the last code-snippet below. Yes, only get; set; —this is an auto-implemented property (called auto-implemented properties) introduced in C# 3.0.

class Child { public Child() { } public int Age { get; set; } }

The last code-snippet is cleaner, safer and more concise since no additional logic is required in the property accessors, in short, more code efficiency benefits.

12. Namespace Alias Qualifier

The Namespace Alias Qualifier (a.k.a. Aliases) in C# lets developers use the alias name instead of the complete namespace. This is very useful, since namespaces in general can become quite long, an alias becomes very handy. In the code-snippet below, Excel is an alias of the Microsoft.Office.Interop.Excel namespace, yeah the default namespace is long, but we've shorten it.

using Excel = Microsoft.Office.Interop.Excel; var excelapp = new Excel.Application(); excelapp.Visible = true;

13. Object Initializers

The old way, to initialize property values from outside of the class, we would have to write either use a constructor or initialize the properties separately as shown in the first code-snippet:

Child child = new Child(); child.Age = 10; child.Name = "Bryan"; child.StreetAddress = "Seattle, WA 98124";

The code-snippet above, can be written as:

Child child = new Child() { Age = 10, Name = "Bryan", StreetAddress = "Seattle, WA 98124" };

This language feature exists in C# 3.0 and newer versions, but is not supported in C# 1.0 and C# 2.0. In short, this provides a more elegant way to achieve the same thing, in addition, it's a useful shorthand and provides good code productivity.

14. Nullable Types

Every C# developer in the world knows how to work with value types like int, double, bool, char, and so one. They're really useful, but they have one flaw: they simply cannot be set to null, except string which can be set to null. For example, a bool variable can only hold the values true or false, however, putting the question symbol ("?") or as shown below, Nullable it is possible to assign null i.e. undefined.

Nullable<bool> status = null; int? i = null;

15. Type Inference

C# 3.0 introduces the concept of type inference with the var keyword. The var keyword was added to support anonymous types which is another new feature in C# 3.0. Without this keyword, we would not be able to create a variable of an anonymous type if we always needed to specify the type. The best part is that the compiler determines the type automatically.

string[] Elementaryschools = {"Adams Elementary", "Hyde Elementary School", "Brookland Elementary", "Meyer Elementary School", "Thomas Elementary School", "Young Elementary School"}; var school = from name in Elementaryschools where name[0] == 'T' select name; foreach (string n in school) Console.WriteLine(n);

The output in the console application will be:

Thomas Elementary School

The main reason "Thomas Elementary School" is printed out, is because we say: where name[0] == 'T', we select only the name if it begins with a 'T'. I just wanted to give some code explanation, in case it becomes complicated. The following two declarations of i are functionally equivalent:

int i = 25; //Explicitly typed var i = 25; //Implicitly typed

16. Lambda Expressions

Lambda expressions were introduced in C# 3.0, and they use the lambda operator =>. Lambda expressions provide a more concise, functional syntax for writing anonymous methods (note: anonymous methods were introduced in C# 2.0). Since functional programming requires a more declarative style of writing code, lambda expressions are handy, in short, lambda expressions are simply functions/methods.

The following code-snippet shows the definition of a delegate and a method that can be used to initialize the delegate:

public delegate int DoubleInteger(int x); class DelegateSample { static public int DoubleNow(int x) { return x * 2; } }

Create and initialize an instance of the delegate, and then call it:

DoubleInteger dint = new DoubleInteger(DelegateSample.DoubleNow); Console.WriteLine("{0}", dint(16));

Using lambda expressions, the syntax gets even terser:

DoubleInteger dint = x => x * 2; Console.WriteLine("{0}", dint(16));

Lambda expressions provide a powerful shorthand that can be used to significantly speed up C# development. In short, lambda expressions allow C# developers to shorten their code significantly and make it more compact form, isn't this good huh? Of course it is good especially if we want to achieve productivity.

17. Optional and Named Parameters in C# 4.0

C# 4.0 introduces optional and named parameters. Named parameters free us from the need to remember or to look up the order of parameters in the parameter lists of invoked methods. Optional parameters enable us to omit arguments for some parameters. These two language features can be used with Microsoft Office Automation APIs—this is what the second code-snippet demonstrates below.

Word.Application wordapp = new Word.Application() { Visible = true }; object MissingValue = System.Reflection.Missing.Value; object Filename = @"C:\sampledocument.docx"; object ReadOnly = true; wordapp.Documents.Open(ref Filename, ref MissingValue, ref ReadOnly, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue, ref MissingValue);

With the support of optional and named parameters this becomes even shorter:

Word.Application wordapp = new Word.Application() { Visible = true }; wordapp.Documents.Open(@"C:\sampledocument.docx", ReadOnly: true);

The Microsoft.Office.Interop.Word has a method, Documents.Open this method has one required parameter, and 15 optional paramters, that's a lot huh? Thanks to named paramters we're able to omit a few or all the optional paramters by using their names and passing the argument value for each—as already demonstrated in the second code-snippet above, ReadOnly: true.