You will need Visual Studio 2005 or higher. (Released April 2005). .NET Framework. 2.0.
C++ has template classes. C# now has generics.
// The old way. System.Collections.ArrayList
var al = new ArrayList();
al.Add(20);
al.Add("Jane");
var aNumber = (int)al[0];
var aString = (string)al[1];
// The new way. System.Collections.Generic
var intList = new List<int>();
intList.Add(20);
var aNumber = intList[0];
Anonymous methods, in contrast to Named Methods, have no name. They are declared using the delegate keyword, and can be used in any place that a Named Method is valid.
Anonymous methods are used to write inline code.
void Test()
{
var t = new System.Timers.Timer();
t.Interval = 1000;
t.Elapsed += TimerElapsed; // Using a Named Method
// Using an anonymous method
t.Elapsed += delegate(object sender, ElapsedEventArgs e)
{
Console.WriteLine("{0}: Tick - Anon", AppDomain.GetCurrentThreadId());
};
t.Start();
Thread.Sleep(3000);
}
// This is a Named Method
void TimerElapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("{0}: Tick - Named", AppDomain.GetCurrentThreadId());
}
A nullable type can represent all of the values of the underlying type, e.g. int, but can also have the value null.
This allows an additional state of value not set.
void TestNullable()
{
System.Nullable<int> age;
// OR
int? age;
age = 22;
if (age.HasValue)
{
Console.WriteLine("Age is {0}", age.Value);
}
int ageValue = age.GetValueOrDefault();
}
Allows the definition of a class, struct or interface, to be split over multiple source files.
// Program1.cs
partial class Program
{
static void Main(string[] args)
{
// main code here
}
}
// Program2.cs
partial class Program
{
void HandleError(Exception ex)
{
// error handling code here
}
}
Easily create IEnumerable collections using the yield return keyword.
void Test1()
{
// example 1
var primes = FivePrimes();
foreach(int prime in primes)
{
Console.WriteLine(prime);
}
// example 2
var days = new DaysOfTheWeek();
foreach (string day in days)
{
Console.WriteLine(day);
}
}
// using a function
IEnumerable<int> FivePrimes()
{
yield return 1;
yield return 3;
yield return 5;
yield return 7;
yield return 9;
}
// using a class
public class DaysOfTheWeek : IEnumerable
{
string[] m_Days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };
public IEnumerator GetEnumerator()
{
for (int i = 0; i < m_Days.Length; i++)
{
yield return m_Days[i];
}
}
}
You can now use different accessibility levels on get and set property acessors.
class MyClass
{
string _name;
public string Name
{
// note: as always, this has the same accessibility as the parent property, in this case public
get
{
return _name;
}
// protected = accessibility is limited to the containing type and those derived from it
protected set
{
_name = value;
}
}
}
Simplified delegate syntax. Assign a MethodGroup to a delegate.
delegate void LogDelegate(string message);
private void LogMethod(string message)
{
Console.WriteLine(message);
}
private void TestMethod1()
{
// old syntax
LogDelegate d1 = new LogDelegate(LogMethod);
// new syntax
LogDelegate d2 = LogMethod;
d1("Test");
d2("Test");
}
The terms covariance and contravariance describe how the compiler matches a method signature to a type.
The prefix co- means with. The prefix contra- means against. And variance means a deviation or difference.
So:
co-variance == with the difference (more derived).
contra-variance == against the difference (less derived).
Covariance allows a method to have a more derived return type than that of the original (delegate) type.
Contravariance allows a method to have less derived arguments than that of the original (delegate) type.
delegate object HandleExceptionDelegate(ApplicationException e);
void Test1()
{
HandleExceptionDelegate del1 = HandleException1; // co-variant
HandleExceptionDelegate del2 = HandleException2; // contra-variant
}
// co-variant
// return type is more derived. more specific. more different.
string HandleException1(ApplicationException ex)
{
return null;
}
// contra-variant
// argument list is less derived. less specific. less different.
object HandleException2(Exception ex)
{
return null;
}
static class MyMath
{
private static double PI = 3.14159;
// static ctor
static MyMath()
{
}
public static double GetPi()
{
return PI;
}
}
void Test1()
{
var pi = MyMath.GetPi();
}