C Sharp (programming language)
C# (pronounced C Sharp) is a multi-paradigm programming language that encompasses functional, imperative, generic and object-oriented (class-based) programming disciplines. It is developed by Microsoft as part of the .NET initiative and later approved as a standard by ECMA (ECMA-334) and ISO (ISO/IEC 23270). Anders Hejlsberg, the designer of Delphi, leads development of the C# language, which has an object-oriented syntax based on C++ and includes influences from aspects of several other programming languages (most notably Delphi and Java) with a particular emphasis on simplification.
Design goals
The ECMA standard lists these design goals for C#:
- C# is intended to be a simple, modern, general-purpose, object-oriented programming language.
- Because software robustness, durability and programmer productivity are important, the language should include strong type checking, array bounds checking, detection of attempts to use uninitialized variables, source code portability, and automatic garbage collection.
- The language is intended for use in developing software components that can take advantage of distributed environments.
- Programmer portability is very important, especially for those programmers already familiar with C and C++.
- Support for internationalization is very important.
- C# is intended to be suitable for writing applications for both hosted and embedded systems, ranging from the very large that use sophisticated operating systems, down to the very small having dedicated functions.
- Although C# applications are intended to be economical with regard to memory and processing power requirements, the language is not intended to compete directly on performance and size with C or assembly language.
History
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.[5] By the time the .NET project was publicly announced at the July 2000 Professional Developers Conference (PDC), 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
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.
C# differs from C and C++ as much as it resembles Java, including:
- There are no global variables or functions. All methods and members must be declared within classes. It is possible, however, to use static methods/variables within public classes instead of global variables/functions.
- Local variables cannot shadow variables of the enclosing block, unlike C and C++. Variable shadowing is often considered confusing by C++ texts.
- C# supports a strict boolean type, bool. Statements that take conditions, such as while and if, require an expression of a boolean type. While C++ also has a boolean type, it can be freely converted to and from integers, and expressions such as if(a) require only that a is convertible to bool, allowing a to be an int, or a pointer. C# disallows this "integer meaning true or false" approach on the grounds that forcing programmers to use expressions that return exactly bool can prevent certain types of programming mistakes such as if (a = b) (use of = instead of ==).
- In C#, memory address pointers can only be used within blocks specifically marked as unsafe, and programs with unsafe code need appropriate permissions to run. Most object access is done through safe references, which cannot be made invalid. An unsafe pointer can point to an instance of a value-type, array, string, or a block of memory allocated on a stack. Code that is not marked as unsafe can still store and manipulate pointers through the System.IntPtr type, but cannot dereference them.
- Managed memory cannot be explicitly freed, but is automatically garbage collected. Garbage collection addresses memory leaks. C# also provides direct support for deterministic finalization with the using statement (supporting the Resource Acquisition Is Initialization idiom).
- Multiple inheritance is not supported, although a class can implement any number of interfaces. This was a design decision by the language's lead architect to avoid complication, avoid dependency hell and simplify architectural requirements throughout CLI.
- C# is more typesafe than C++. The only implicit conversions by default are those which are considered safe, such as widening of integers and conversion from a derived type to a base type. This is enforced at compile-time, during JIT, and, in some cases, at runtime. There are no implicit conversions between booleans and integers and between enumeration members and integers (except 0, which can be implicitly converted to an enumerated type), and any user-defined conversion must be explicitly marked as explicit or implicit, unlike C++ copy constructors (which are implicit by default) and conversion operators (which are always implicit).
- Enumeration members are placed in their own namespace.
- Accessors called properties can be used to modify an object with syntax that resembles C++ member field access. In C++, declaring a member public enables both reading and writing to that member, and accessor methods must be used if more fine-grained control is needed. In C#, properties allow control over member access and data validation.
- Full type reflection and discovery is available.
- C# currently (as of 3 June 2008) has 77 reserved words.
Common Type system (CTS)
C# has a unified type system. This unified type system is called Common Type System (CTS).
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:
- Value Type
- Reference Type
While value types are those in which the value itself is stored by allocating memory on the stack, reference types are those in which only the address to the location where the value is present, is stored. Value types include integers (short, long), floating-point numbers (float, double), decimal (a base 10 number), structures, enumerations, booleans and characters while reference types include objects, strings, classes, interfaces and delegates.
User-defined datatypes
C# also allows the programmer to create user-defined value types, using the struct keyword. From the programmer's perspective, they can be seen as lightweight classes. Unlike regular classes, and like the standard primitives, such value types are allocated on the stack rather than on the heap. They can also be part of an object (either as a field or boxed), or stored in an array, without the memory indirection that normally exists for class types. Structs also come with a number of limitations. Because structs have no notion of a null value and can be used in arrays without initialization, they are implicitly initialized to default values (normally by filling the struct memory space with zeroes, but the programmer can specify explicit default values to override this). The programmer can define additional constructors with one or more arguments. This also means that structs lack a virtual method table, and because of that (and the fixed memory footprint), they cannot allow inheritance (but can implement interfaces).
Type casting in C#
Type casting is the process of converting a value belonging to a particular data type (or instance) to another.
Example:
usingSystem;
class Employee {}
class ContractEmployee : Employee
{
}
class CastExample5
{
publicstaticvoidMain()
{
Employee e = new Employee();
Console.WriteLine("e = {0}",
e == null ? "null" : e.ToString());
ContractEmployee c = e as ContractEmployee;
Console.WriteLine("c = {0}",
c == null ? "null" : c.ToString());
}
}
Here, the element e, which is an instance of the class Employee, is type cast as an instance of the class ContractEmployee and stored in element c.
Certain datatypes are incompatible for type casting. For example, an integer value cannot be type-casted into a string though the converse is possible. With regard to user-defined data types, the compiler allows all kinds of type-casting. However, an InvalidCastException is thrown at runtime if the datatypes are incompatible.
Boxing and unboxing
Boxing and unboxing are two new concepts introduced in C#.
Boxing is the method used to convert a value type into a reference type.
Example:
int foo = 42; // Value type...
object bar = foo; // foo is boxed to bar.
Unboxing is the method used to convert a reference type into a value type.
Example:
int foo = 42; // Value type.
object bar = foo; // foo is boxed to bar.
int foo2 = (int)bar; // Unboxed back to value type.
Boxing and unboxing become important when value types are put into a collection class or taken out of a collection class.
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 class implementation across more than one source file. This permits splitting up very large classes, and is also useful if some parts of a class are automatically generated.
file1.cs:
public partial class MyClass
{
publicvoid MyMethod1()
{
// implementation
}
}
file2.cs:
public partial class MyClass
{
publicvoid MyMethod2()
{
// implementation
}
}
Generics
Generics, or parameterized types, 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.[7]
Static classes that cannot be instantiated
Static classes that cannot be instantiated, and that only allow static members. This is similar to the concept of module 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.
publicstatic IEnumerable<int> GetEven(IEnumerable<int> numbers)
{
foreach(int i in numbers)
{
if(i % 2 == 0) yield return i;
}
}
Anonymous delegates
Anonymous delegates providing closure-like functionality.[8]
publicvoid Foo(object parameter){
// ...
ThreadPool.QueueUserWorkItem(delegate)
{
// anonymous delegates have full access to local variables of the enclosing method
if(parameter == ...)
{
// ...
}
// ...
});
}
Covariance and contravariance for signatures of delegates
Covariance and contravariance for signatures of delegates[9]
The accessibility of property accessors can be set independently
Example:
string status = string.Empty;
publicstring 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[citation needed], 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 = newObject();
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; // Unless i is 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 November2007 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.[10]
Linq
Language Integrated Query:[11] "from, where, select" context-sensitive keywords allowing queries across SQL, XML, collections, and more. These are treated as keywords in the LINQ context, but their addition won't break existing variables named from, where, or select.
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[12])
Anonymous types
var x = new { Name = "James" }
Local variable type inference
Local variable type inference: var x = "hello"; is interchangeable with string x = "hello";. More than just syntactic sugar, this feature is required for the declaration of anonymous typed variables.
Lambda expressions
Lambda expressions: listOfFoo.Where(delegate(Foo x) { return x.Size > 10; }) can be written listOfFoo.Where(x => x.Size > 10);
Compiler-inferred translation of Lambda expressions to either strongly-typed function delegates or strongly-typed expression trees.
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 (adding methods to classes by including the this keyword in the first parameter of a method on another static class):
publicstaticclass IntExtensions
{
publicstaticvoid PrintPlusOne(thisint x){ Console.WriteLine(x + 1); }
}
int foo = 0;
foo.PrintPlusOne();
Partial methods
Allow codegenerators 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.[13]
C# 3.0 was unveiled at the 2005 Professional Developers Conference.[14] It is not currently standardized by any standards organisation, though it is expected that it will eventually become an ECMA and then ISO standard, as did its predecessors.
Microsoft has emphasized that the new language features of C# 3.0 will be available without any changes to the runtime. This means that C# 2.0 and 3.0 will be binary-compatible (CLI implementations compatible with 2.0 are able to run 3.0 applications directly).
Although the new features may only slightly change simple in-memory queries, such as List.FindAll or List.RemoveAll, the pattern used by LINQ allows for significant extension points to enable queries over different forms of data, both local and remote.
Preprocessor
C# features "preprocessor directives"[15] (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 (*/).
publicclass Foo
{
// a comment
publicstaticvoid Bar(int firstParam){} //Also a comment
}
publicclass FooBar
{
/* a comment */
publicstaticvoid BarFoo(int firstParam){} /* Also a comment */
}
Multi-line comments can also be indicated by a starting forward slash/asterisk (/*) and ending asterisk/forward slash (*/).
publicclass Foo
{
/* A Multi-Line
comment */
publicstaticvoid 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 ///.
publicclass Foo
{
/// <summary>A summary of the method.</summary>
/// <param name="firstParam">A description of the parameter.</param>
/// <remarks>Remarks about the method.</remarks>
publicstaticvoid Bar(int firstParam){}
}
Multi-line comments, while defined in the version 1.0 language specification, were not supported until the .NET 1.1 release.[16] These comments are designated by a starting forward slash/asterisk/asterisk (/**) and ending asterisk/forward slash (*/)[17].