Dynamically typed objects
Dynamically typed objects make it easier to communicate with dynamic languages such as Python and JavaScript:
dynamic calc = GetCalculator();intsum = calc.Add(3, 5);Run-time typing:
dynamic name = “John”; // typed as Stringdynamic age = 29; // typed as Int32dynamic qty = 21.23m; // typed as DecimalThe type of the variable is determined at runtime:
Deferred method resolution:
dynamic x = ...;dynamic y = ...;dynamic min = Math.Min(x, y);The method that is called on a dynamic object will be resolved at runtime:
In the example, one of the following might be called:
Math.Min(int, int); Math.Min(decimal, decimal);
Math.Min(byte, byte);
Optional and named parameters
Traditionally, one would have to override a method to support signatures with varying parameters:
void Open(string path,FileModemode,FileAccessaccess,FileShareshare);void Open(string path,FileModemode,FileShareshare);void Open(string path,FileModemode);void Open(string path);Optional and named parameters allow us to specify default values for parameters that are not passed to the function:void Open(string path,FileModemode = FileMode.Open,FileAccessaccess = FileAccess.Read,FileShareshare = FileShare.Both);Function declaration
Calling the function is a matter of specifying the required parameters and the optional ones one would want to use:Open(“foo.txt”, FileMode.CreateNew);Open(“foo.txt”, access:FileAccess.Both);Function invocation
Parameters can be specified in any order provided they are named:
Open(access:FileAccess.Read,path:“foo.txt”,share:FileShare.None,mode:FileMode.Truncate);Improved COM interoperability
COM from C# 3.0 and earlier was quite verbose:
string file = “foo.xls”;object missing = Missing.Value;document.Open(ref file, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing);Thanks to optional and named parameters, COM from C# 4.0 is a lot more terse:
document.Open(“foo.xls”);Safe co-and contra-variance
In C# 3.0 generics were invariant. This means that they could not be reliably cast from one generic to another. For example, the following would fail:
List<string> strings;IEnumerable<string> list = strings; // passIEnumerable<object> list = strings; // failIn C# 4.0 one can create generics to be safely covariant by specifying the outkeyword in the definition of a generic interface:
public interface IEnumerable<outT>{ IEnumerator<T> GetEnumerator();}Safe contra-variance
Safe co-variance
Similarly one can enforce safe contra-variance by specifying the inkeyword in the definition of a generic interface:
public interface ICompare<inT>{ intCompare(T x, T y);}