C#
Paradigm structured, imperative, object-oriented.
Appeared in 2001
Designed by Microsoft Corporation
Latest release 3/ 19 November 2007
Typing discipline static, strong, safe, nominative
Major implementations .NET Framework, Mono, DotGNU
Influenced by Object Pascal, C++, Modula-3, Java, Eiffel
Influenced F#, Nemerle, D, Java[1], Vala, Windows PowerShell

C# (pronounced C Sharp) is a multi-paradigm programming language that encompasses functional, imperative, generic, object-oriented (class-based), and component-oriented programming disciplines. It was developed by Microsoft as part of the .NET initiative and later approved as a standard by ECMA (ECMA-334) and ISO (ISO/IEC 23270). C# is one of the 44 programming languages supported by the .NET Framework's Common Language Runtime and is used extensively with Microsoft Visual Studio .NET.

C# is intended to be a simple, modern, general-purpose, object-oriented programming language. Anders Hejlsberg, the designer of Delphi, leads the team which is developing C#. It has an object-oriented syntax based on C++ and is heavily influenced by other programming languages such as Delphi and Java. It was initially named Cool, which stood for "C like Object Oriented Language". However, in July 2000, when Microsoft made the project public, the name of the programming language was given as C#. The most recent release is C# 3.0 which is used with Microsoft Visual Studio 2008. The next proposed version, C# 4.0, is still under development.

Contents

Design goals

The ECMA standard lists these design goals for C#:

History

In 1996, Sun Microsystems released the Java programming language with Microsoft soon purchasing a license to implement it in their operating system. Java was originally meant to be a platform independent language, but Microsoft, in their implementation, broke their license agreement and made a few changes that would essentially inhibit Java's platform-independent capabilities. Sun filed a lawsuit and Microsoft settled, deciding to create their own version of a partially compiled, partially interpreted object-oriented programming language with syntax closely related to that of C++.

During the development of .NET, the class libraries were originally written in a language/compiler called Simple Managed C (SMC).[2][3][4] In January 1999, Anders Hejlsberg formed a team to build a new language at the time called Cool, which stood for "C like Object Oriented Language".[5] Microsoft had considered keeping the name "Cool" as the final name of the language, but chose not to do so for trademark reasons. By the time the .NET project was publicly announced at the July 2000 Professional Developers Conference, the language had been renamed C#, and the class libraries and ASP.NET runtime had been ported to C#.

C#'s principal designer and lead architect at Microsoft is Anders Hejlsberg, who was previously involved with the design of Visual J++, Borland Delphi, and Turbo Pascal. In interviews and technical papers he has stated that flaws in most major programming languages (e.g. C++, Java, Delphi, and Smalltalk) drove the fundamentals of the Common Language Runtime (CLR), which, in turn, drove the design of the C# programming language itself. Some argue that C# shares roots in other languages.[6]

Features

Note: The following description is based on the language standard and other documents listed in the external links section.

By design, C# is the programming language that most directly reflects the underlying Common Language Infrastructure (CLI). Most of C#'s intrinsic types correspond to value-types implemented by the CLI framework. However, the C# language specification does not state the code generation requirements of the compiler: that is, it does not state that a C# compiler must target a Common Language Runtime (CLR), or generate Common Intermediate Language (CIL), or generate any other specific format. Theoretically, a C# compiler could generate machine code like traditional compilers of C++ or FORTRAN; in practice, all existing C# implementations target CIL.

Some notable C# distinguishing features are:

Common Type system (CTS)

C# has a unified type system. This unified type system is called Common Type System (CTS).[7]

A unified type system implies that all types, including primitives such as integers, are subclasses of the System.Object class. For example, every type inherits a ToString() method. For performance reasons, primitive types (and value types in general) are internally allocated on the stack.

Categories of datatypes

CTS separates datatypes into two categories[7]:

Value types are plain aggregations of data. Instances of value types do not have referential identity nor a referential comparison semantics - equality and inequality comparisons for value types compare the actual data values within the instances, unless the corresponding operators are overloaded. Values of reference types always have a default value, and can always be created and copied. Some other limitations on value types are that they cannot derive from each other (but can implement interfaces) and cannot have a default (parameterless) constructor. Examples of value types are some primitive types, such as int (a signed 32-bit integer), float (a 32-bit IEEE floating-point number), char (a 16-bit Unicode codepoint), and System.DateTime (identifies a specific point in time with millisecond precision).

In contrast, reference types have the notion of referential identity - each instance of reference type is inherently distinct from every other instance, even if the data within both instances is the same. This is reflected in default equality and inequality comparisons for reference types, which test for referential rather than structural equality, unless the corresponding operators are overloaded (such as the case for System.String). In general, it is not always possible to create an instance of a reference type, nor to copy an existing instance, or perform a value comparison on two existing instances, though specific reference types can provide such services by exposing a public constructor or implementing a corresponding interface (such as ICloneable or IComparable). Examples of reference types are object (the ultimate base class for all other C# classes), System.String (a string of Unicode characters), and System.Array (a base class for all C# arrays).

Both type categories are extensible with user-defined types.

Boxing and unboxing

Boxing is the operation of converting a value of a value type into a value of a corresponding reference type.[7]

Example:

int foo = 42;         // Value type...
object bar = foo;     // foo is boxed to bar.

Unboxing is the operation of converting a value of a reference type (previously boxed) into a value of a value type.[7]

Example:

int foo = 42;         // Value type.
object bar = foo;     // foo is boxed to bar.
int foo2 = (int)bar;  // Unboxed back to value type.

Features of C# 2.0

New features in C# for the .NET SDK 2.0 (corresponding to the 3rd edition of the ECMA-334 standard) are:

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 primary useful when parts of a class are automatically generated. 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#. 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.[8]

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.

A new form of iterator providing generator functionality

A new form of iterator that provides generator functionality, using a yield return construct similar to yield in Python.

// Method that takes an iterable input (possibly an array)
// and returns all even numbers.
public static IEnumerable<int> GetEven(IEnumerable<int> numbers)
{
    foreach (int i in numbers)
    {
        if (i % 2 == 0) yield return i;
    }
}

Anonymous delegates

Anonymous delegates provide closure functionality in C#.[9] Code inside the body of an anonynous 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;
}

Delegate covariance and contravariance

Conversions from method groups to delegate types are covariant and contravariant in return and parameter types, respectively. [10]

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 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 types received an eleventh-hour improvement at the end of August 2005, mere weeks 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<T> 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)
    Console.WriteLine("Correct behaviour - runtime version from September 2005 or later");
else
    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[11] , since it required core-CLR changes affecting not only .NET2, but all dependent technologies (including C#, VB, SQL Server 2005 and Visual Studio 2005).

Coalesce operator

(??) returns the first of its operands which is not null (or null, if no such operand exists):

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.

Features of C# 3.0

C# 3.0 is the current version, and was released on 19 November 2007 as part of .NET Framework 3.5. It includes new features inspired by functional programming languages such as Haskell and ML, and is driven largely by the introduction of the Language Integrated Query (LINQ) pattern to the Common Language Runtime.[12] It is not currently standardized by any standards organisation.


LINQ (Language-Integrated Query)

LINQ is an extensible, general-purpose query language for many kinds of data sources (including plain object collections, XML documents, databases, and so on) which is tightly integrated with other C# language facilities. The syntax heavily borrows from SQL. An example:

int[] array = { 1, 5, 2, 10, 7 };
 
// Select squares of all odd numbers in the array sorted in descending order
IEnumerable<int> query = from x in array
                         where x % 2 == 1
                         orderby x descending
                         select x * x;

Object initializers

Customer c = new Customer(); c.Name = "James";

can be written

Customer c = new Customer { Name="James" };

Collection initializers

MyList list = new MyList();
list.Add(1);
list.Add(2);

can be written as

MyList list = new MyList { 1, 2 };

assuming that MyList implements System.Collections.IEnumerable and has a public Add method[13]

Anonymous types

var x = new { FirstName="James", LastName="Frank" }; [14]

Local variable type inference

Local variable type inference:

var x = new Dictionary<string, List<float>>();

is interchangeable with

Dictionary<string, List<float>> x = new Dictionary<string, List<float>>();

This feature is not just a convenient syntactic sugar for shorter local variable declarations, but it is also required for the declaration of variables of anonymous types.

Lambda expressions

Lambda expressions provide a concise way to write first-class anonymous function values. Compare the following C# 2.0 snippet:

listOfFoo.Where(delegate(Foo x) { return x.Size > 10; })

with this C# 3.0 equivalent:

listOfFoo.Where(x => x.Size > 10);

In the above examples, lambda expressions are merely short-hand syntax for anonymous delegates with type inference for parameters and return type. However, depending on the context they are used in, a C# compiler can also transform lambdas into ASTs that can then be processed at run-time. In the example above, if listOfFoo is not a plain in-memory collection, but a wrapper around a database table, it could use this technique to translate the body of the lambda into the equivalent SQL expression for optimized execution. Either way, the lambda expression itself looks exactly the same in the code, so the way it is used at run-time is transparent to the client.

Automatic properties

The compiler will automatically generate a private instance variable and the appropriate getter and setter given code such as: public string Name { get; private set; }

Extension methods

Extension methods are a form of syntactic sugar providing the illusion of adding new methods to the existing class outside its definition. In practice, an extension method is a static method that is callable as if it was an instance method; the receiver of the call is bound to the first parameter of the method, decorated with keyword this:

public static class StringExtensions
{
    public static string Left(this string s, int n)
    {
        return s.Substring(0, n);
    }
}
 
string s = "foo";
s.Left(3); // same as StringExtensions.Left(s, 3);

Partial methods

Partial methods allow code generators to generate method declarations as extension points that are only included in the source code compilation if someone actually implements it in another portion of a partial class.[15]

Preprocessor

C# features "preprocessor directives"[16] (though it does not have an actual preprocessor) based on the C preprocessor that allow programmers to define symbols but not macros. Conditionals such as #if, #endif, and #else are also provided. Directives such as #region give hints to editors for code folding.

Code comments

C# utilizes a double forward slash (//) to indicate the rest of the line is a comment. Comments can also be indicated using a starting forward slash/asterisk (/*) and ending asterisk/forward slash (*/).

public class Foo
{
    // a comment
    public static void Bar(int firstParam) {}  //Also a comment
}
 
public class FooBar
{
    /* a comment */
    public static void BarFoo(int firstParam) {}  /* Also a comment */
}

Multi-line comments can also be indicated by a starting forward slash/asterisk (/*) and ending asterisk/forward slash (*/).

public class Foo
{
    /* A Multi-Line
       comment  */
    public static void Bar(int firstParam) {}  
}

XML documentation system

C#'s documentation system is similar to Java's Javadoc, but based on XML. Two methods of documentation are currently supported by the C# compiler.

Single-line comments, such as those commonly found in Visual Studio generated code, are indicated on a line beginning with ///.

public class Foo
{
    /// <summary>A summary of the method.</summary>
    /// <param name="firstParam">A description of the parameter.</param>
    /// <remarks>Remarks about the method.</remarks>
    public static void Bar(int firstParam) {}
}

Multi-line comments, while defined in the version 1.0 language specification, were not supported until the .NET 1.1 release.[17] These comments are designated by a starting forward slash/asterisk/asterisk (/**) and ending asterisk/forward slash (*/)[18].

public class Foo
{
    /** <summary>A summary of the method.</summary>
     *  <param name="firstParam">A description of the parameter.</param>
     *  <remarks>Remarks about the method.</remarks> */
    public static void Bar(int firstParam) {}
}

Note there is some stringent criteria regarding white space and XML documentation when using the forward slash/asterisk/asterisk (/**) technique.

This code block:

/** 
 * <summary>
 * A summary of the method.</summary>*/

produces a different XML comment than this code block[18]:

/** 
 * <summary>
   A summary of the method.</summary>*/

Syntax for documentation comments and their XML markup is defined in a non-normative annex of the ECMA C# standard. The same standard also defines rules for processing of such comments, and their transformation to a plain XML document with precise rules for mapping of CLI identifiers to their related documentation elements. This allows any C# IDE or other development tool to find documentation for any symbol in the code in a certain well-defined way.

Future development

The next version of the language, C# 4.0, is under development as of October 2008. Microsoft has announced a list of new language features in C# 4.0 on Microsoft Professional Developers Conference 2008. The major focus of the next version is interoperability with partially or fully dynamically typed languages and frameworks, such as the dynamic language runtime and COM. The following new features were announced[19]:

Covariant and contravariant generic type parameters

Generic interfaces and delegates can have their type parameters marked as covariant or contravariant, using keywords out and in, respectively. These declarations are then respected for type conversions, both implicit and explicit, and both compile-time and run-time. For example, the existing interface IEnumerable<T> has been redefined as follows:

interface IEnumerable<out T>
{
  IEnumerator<T> GetEnumerator();
}

Therefore, any class that implements IEnumerable<Derived> for some class Derived is also considered to be compatible with IEnumerable<Base> for all classes and interfaces Base that Derived extends, directly, or indirectly. In practice, it makes it possible to write code such as:

void PrintAll(IEnumerable<object> objects)
{
  foreach (object o in objects)
  {
    Console.WriteLine(o);
  }
}
 
IEnumerable<string> strings = new List<string>();
PrintAll(strings); // IEnumerable<string> is implicitly converted to IEnumerable<object>

For contravariance, the existing interface IComparer<T> has been redefined as follows:

public interface IComparer<in T>
{
    int Compare(T x, T y);
}

Therefore, any class that implements IComparer<Base> for some class Base is also considered to be compatible with IComparer<Derived> for all classes and interfaces Derived that is extended from Base. It makes it possible to write code such as:

IComparer<object> objectComparer = GetComparer();
IComparer<string> stringComparer = objectComparer;

Dynamic member lookup

A new pseudo-type dynamic is introduced into the C# type system. It is treated as System.Object, but in addition, any member access (method call; field, property, or indexer access; or a delegate invocation) or application of an operator on a value of such type is permitted without any type checking, and its resolution is postponed until run-time. For example:

  // Returns the value of Length property or field of any object
  int GetLength(dynamic obj)
  {
    return obj.Length;
  }
 
  GetLength("Hello, world");        // a string has a Length property,
  GetLength(new int[] { 1, 2, 3 }); // and so does an array,
  GetLength(42);                    // but not an integer - an exception will be thrown here at run-time

Dynamic method calls are triggered by a value of type "dynamic" as any implicit or explicit parameter (and not just a receiver). For example:

  void Print(dynamic obj)
  {
     Console.WriteLine(obj); // which overload of WriteLine() to call is decided at run-time
  }
 
  Print(123);   // ends up calling WriteLine(int)
  Print("abc"); // ends up calling WriteLine(string)

Dynamic lookup is performed using three distinct mechanisms: COM IDispatch for COM objects, IDynamicObject DLR interface for objects implementing that interface, and Reflection for all other objects. Any C# class can therefore intercept dynamic calls on its instances by implementing IDynamicObject.

In case of dynamic method and indexer calls, overload resolution happens at run-time according to the actual types of the values passed as arguments, but otherwise according to the usual C# overloading resolution rules. Furthermore, in cases where the receiver in a dynamic call is not itself dynamic, run-time overload resolution will only consider the methods that are exposed on the declared compile-time type of the receiver. For example:

class Base
{
  void Foo(double x);
}
 
class Derived : Base
{
  void Foo(int x);
}
 
dynamic x = 123;
Base b = new Derived();
b.Foo(x); // picks Base.Foo(double) because b is of type Base, and Derived.Foo(int) is not exposed
dynamic b1 = b;
b1.Foo(x); // picks Derived.Foo(int)

Any value returned from a dynamic member access is itself of type dynamic. Values of type dynamic are implicitly convertible both from and to any other type. In the code sample above, this permits GetLength function to treat the value returned by a call to Length as an integer without any explicit cast. At run-time, the actual value will be converted to the requested type.

Optional ref Keyword

The ref keyword for callers of methods is now optional. The following code

void Increment(ref int x)
{
  ++x;
}
 
int x = 0;
Increment(ref x);

can now be written as

void Increment(ref int x)
{
  ++x;
}
 
int x = 0;
Increment(x);

Optional parameters and named arguments

C# 4.0 introduces optional parameters with default values as seen in C++. For example:

void Increment(ref int x, int dx = 1)
{
  x += dx;
}
 
int x = 0;
Increment(ref x);    // dx takes the default value of 1
Increment(x, 2); // dx takes the value 2

In addition, to complement optional parameters, it is possible to explicitly specify parameter names in method calls, allowing to selectively pass any given subset of optional parameters for a method. The only restriction is that named parameters must be placed after the unnamed parameters. Parameter names can be specified for both optional and required parameters, and can be used to improve readability or arbitrarily reorder arguments in a call. For example:

Stream OpenFile(string name, FileMode mode = FileMode.Open, FileAccess access = FileAccess.Read) { ... }
 
OpenFile("file.txt"); // use default values for both "mode" and "access" 
OpenFile("file.txt", mode: FileMode.Create); // use default value for "access"
OpenFile("file.txt", access: FileAccess.Read); // use default value for "mode"
OpenFile(name: "file.txt", access: FileAccess.Read, mode: FileMode.Create); // name all parameters for extra readability, and use order different from method declaration

Optional parameters make inter-operating with COM easier. Previously, C# has to pass in every parameter in the method of the COM component, even those that are optional. For example:

object fileName = "Test.docx";
object missing = System.Reflection.Missing.Value;
 
doc.SaveAs(ref fileName,
    ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing);

With support for optional parameters, the code can be shortened as

doc.SaveAs(ref fileName);

Indexed properties

Indexed properties (and default properties) of COM objects are now recognised, but C# objects still do not support them.

Libraries

The C# specification details a minimum set of types and class libraries that the compiler expects to have available. In practice, C# is most often used with some implementation of the Common Language Infrastructure (CLI), which is standardized as ECMA-335 Common Language Infrastructure (CLI).

Hello world example

The following is a very simple C# program, a version of the classic "Hello world" example:

class ExampleClass
{
    static void Main()
    {
        System.Console.WriteLine("Hello, world!");
    }
}

The effect is to write the following text to the output console:

Hello, world!

Each line has a purpose:

class ExampleClass

Above is a class definition. Everything between the following pair of braces describes ExampleClass.

static void Main()

This declares the class member method where the program begins execution. The .NET runtime calls the Main method. (Note: Main may also be called from elsewhere, e.g. from the code Main() in another method of ExampleClass.) The static keyword makes the method accessible without an instance of ExampleClass. Each console application's Main entry point must be declared static. Otherwise, the program would require an instance, but any instance would require a program. To avoid that irresolvable circular dependency, C# compilers processing console applications (like above) report an error if there is no static Main method. The void keyword declares that Main has no return value (see also side effect).

Console.WriteLine("Hello, world!");

This line writes the output. Console is a static class in the System namespace. It provides an interface to the standard input, output, and error streams for console applications. The program calls the Console method WriteLine, which displays on the console a line with the argument, the string "Hello, world!".

Standardization

In August, 2000, Microsoft Corporation, Hewlett-Packard and Intel Corporation co-sponsored the submission of specifications for C# as well as the Common Language Infrastructure (CLI) to the standards organization ECMA International. In December 2001 , ECMA released ECMA-334 C# Language Specification. C# became an ISO standard in 2003 (ISO/IEC 23270:2006 - Information technology -- Programming languages -- C#). ECMA had previously adopted equivalent specifications as the 2nd edition of C#, in December, 2002.

In June 2005, ECMA approved edition 3 of the C# specification, and updated ECMA-334. Additions included partial classes, anonymous methods, nullable types, and generics (similar to C++ templates).

In July 2005, ECMA submitted the standards and related TRs to ISO/IEC JTC 1 via the latter's Fast-Track process. This process usually takes 6-9 months.

Criticism

Programs written for .NET and other similar virtual machine environments tend to run more slowly and require more memory than functionally similar applications written in native languages like C++.[20][21][22]

Although the C# language definition and the CLI are standardized under ISO and ECMA standards, the CLI is only a part of Microsoft's Base Class Library (BCL), which also contains non-standardized classes that are used by many C# programs (some extended IO, User Interface, Web services, ...). Furthermore, parts of the BCL have been patented by Microsoft,[23][24] which may deter independent implementations of the full framework, as only the standardized portions have RAND protection from patent claims.

Implementations

The most commonly used C# compiler is Microsoft Visual C#.

C# compilers are also provided with:

Language name

C sharp typographical convention

The name "C sharp" was inspired from musical notation where a sharp indicates that the written note should be made a half-step higher in pitch.[25] This is similar to the language name of C++, where the ++ symbol indicates that a variable should be incremented by 1.

Due to technical limitations of display (fonts, browsers, etc.) and the fact that the sharp symbol (, U+266F, MUSIC SHARP SIGN) is not present on the standard keyboard, the Number sign (#, U+0023, NUMBER SIGN) was chosen to represent the sharp symbol in the written name of the programming language.[26] This convention is reflected in the ECMA-334 C# Language Specification.[27] However, when it is practical to do so (for example, in advertising or in box art[28]), Microsoft will use the intended musical sharp symbol.

The "sharp" suffix has been used by a number of other .NET languages that are variants of existing languages, including J# (a .NET language also designed by Microsoft which is derived from Java 1.1), A# (from Ada), and the functional F#.[29] The original implementation of Eiffel for .NET was called Eiffel#, a name since retired since the full Eiffel language is now supported. The suffix is also sometimes used for libraries, such as Gtk# (a .NET wrapper for GTK+ and other GNOME libraries), Cocoa# (a wrapper for Cocoa) and Qt# (a .NET language binding for the Qt toolkit).

See also

Environments and tools

Related languages

Comparisons

Notes

  1. ^ In Java 5.0, several features (foreach, autoboxing, varargs, attributes and enums) were introduced, after proving themselves useful in the C# language (with only minor differences in name and implementation). [1][2]
  2. ^ "Jason Zander on the history of .NET". Retrieved on 2008-02-21.
  3. ^ "C# 3.0 New Features". Retrieved on 2008-06-08.
  4. ^ "Scott Guthrie on the origins of ASP.Net". Retrieved on 2008-02-21.
  5. ^ Naomi Hamilton (October 1, 2008). "The A-Z of Programming Languages: C#". Retrieved on 2008-10-01.
  6. ^ "Programming language history chart".
  7. ^ a b c d Archer, Part 2, Chapter 4:The Type System
  8. ^ An Introduction to C# Generics
  9. ^ Anonymous Methods (C#)
  10. ^ Covariance and Contravariance in Delegates (C#)
  11. ^ Somasegar (August 11, 2005). "Nulls not missing anymore". Somasegar's WebLog. MSDN. Retrieved on 2008-11-05.
  12. ^ Tim Anderson (November 14, 2006). "C# pulling ahead of Java - Lead architect paints rosy C# picture". Reg Developer. The Register. Retrieved on 2007-01-20.
  13. ^ The Mellow Musings of Dr. T : What is a collection?
  14. ^ Anonymous Types (C# Programming Guide)
  15. ^ "Partial Methods". Retrieved on 2007-10-06.
  16. ^ C# Preprocessor Directives
  17. ^ Anson Horton (2007-09-11). "C# XML documentation comments FAQ". Retrieved on 2007-12-11.
  18. ^ a b http://msdn2.microsoft.com/en-us/library/5fz4y783(VS.71).aspx Delimiters for Documentation Tags
  19. ^ Mads Torgersen. "New features in C# 4.0". Retrieved on 2008-10-28.
  20. ^ "Computer Language Benchmarks Game". Retrieved on 2008-08-29.
  21. ^ "Microbenchmarking C++, C#, and Java: Average results without arithmetic.". Dr. Dobb's Journal (2005-07-01). Retrieved on 2007-12-29.
  22. ^ "Computer Language Benchmarks Game". Retrieved on 2008-08-29.
  23. ^ See .NET Framework
  24. ^ See Mono and Microsoft’s patents
  25. ^ "C#/.NET History Lesson" (2008-03-25).
  26. ^ "Microsoft C# FAQ". Retrieved on 2008-03-25.
  27. ^ Standard ECMA-334 C# Language Specification. 4th edition (June 2006).
  28. ^ Microsoft.com
  29. ^ "Microsoft F# FAQ".

References

External links

Wikibooks
Wikibooks has a book on the topic of
C Sharp Programming

No comments have been added.



Your name:

City:

Country: