Jump to content

User:Sundström/Drafts/C Sharp syntax

From Wikipedia, the free encyclopedia
Main article: C Sharp (programming language)

This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.

Basics

[edit]

Identifier

[edit]

An identifier is the name of an element in the code. There are certain standard naming conventions to follow when selecting names for elements.

An identifier can:

  • start with a "_".
  • contain both upper case and lower case letters.

An identifier cannot:

  • start with a numeral.
  • start with a symbol, unless it is a keyword (check Keywords).
  • have more than 511 chars.
Keywords
[edit]

Keywords are predefined reserved words with special syntactic meaning. Some of them are only reserved in contextual meaning. Keywords cannot directly be used as identifiers. They can be prefixed with @ for use as identifiers.

C# keywords / C# reserved words
abstract as base bool
break by3 byte case
catch char checked class
const continue decimal default
delegate do double descending3
explicit event extern else
enum false finally fixed
float for foreach from3
goto group3 if implicit
in int interface internal
into3 is lock long
new null namespace object
operator out override orderby3
params private protected public
readonly ref return switch
struct sbyte sealed short
sizeof stackalloc static string
select3 this throw true
try typeof uint ulong
unchecked unsafe ushort using
var3 virtual volatile void
while where3 yield2  
2 - C# 2.0 Keyword
3 - C# 3.0 Keyword

Using a keyword as an identifier.

string @out; // @out is an ordinary identifier, distinct from the 'out' keyword, which retains its special meaning

Literals

[edit]
Integers
octal 0365, 0[0..7]*
hexadecimal 0xF5, 0x[0..9, A..F, a..f]*
decimal 245, [1..9][0..9]*
Floating-point values
float 23.5F, 23.5f; 1.72E3F, 1.72E3f, 1.72e3F, 1.72e3f
double 23.5, 23.5D, 23.5d; 1.72E3, 1.72E3D, ...
Character literals
char 'a', 'Z', '\u0231'
String literals
String "Hello, world"
Characters escapes in strings
Unicode character \u followed by the hexadecimal unicode code point
Tab \t
Backspace \b
Carriage return \r
Form feed \f
Backslash \\
Single quote \'
Double quote \"
Line feed \n

Variables

[edit]

Variables are identifiers associated with values. They are declared by writing the variable's type and name, and are optionally initialized in the same statement by assigning a value.

Declare

int MyInt;         // Declaring an uninitialized variable called 'MyInt', of type 'int'

Initialize

int MyInt;        // Declaring an uninitialized variable
MyInt = 35;       // Initializing the variable

Declare & Initialize

int MyInt = 35;   // Declaring and Initializing the variable at the same time

Multiple variables of the same type can be declared and initialized in one statement.

int a, b;         // Declaring multiple variable of the same type

int a = 2, b = 3; // Declaring an initializing multiple variables of the same type

Type inference

[edit]
This is a feature of C Sharp 3.0.

C# 3.0 introduced type inference, allowing the type specifier of a variable declaration to be replaced by the keyword var, if its actual type can be statically determined from the initializer. This reduces repetition, especially for types with multiple generic type-parameters, and adheres more closely to the DRY principal.

var MyChars = new char[] {'A', 'Ö'}; // or char[] MyChars = new char[] {'A', 'Ö'};

var MyNums = new List<int>();  // or List<int> MyNums = new List<int>();

See also

Constants

[edit]

Constants are values that are immutable and can not change.

const

[edit]

When declaring a local variable or a field with the const-keyword as a prefix the value must be given when it is declared. After that it is locked and cannot change anymore. They can either be declared in the context as a field or a local variable. Constants are implicitly static.

const double PI = 3.14;

This shows all the uses of the keyword.

class Foo
{
    const double x = 3;

    Foo()
    {

        const int y = 2;
    }
}

readonly

[edit]

The readonly keyword does a similar thing to fields. Like fields marked as const they cannot change when initialized. The difference is that you can choose to initialize it in a constructor. This only work on fields. Read-only fields can either be members of an instance or static class members.

class Foo
{
    readonly int value;
    readonly int value2 = 3;
    readonly StringBuilder sb;
    
    Foo()
    {
        value = 2;
        sb = new StringBuilder();
    }
}

Code blocks

[edit]

Through out in C# the operators { ... } are used to signify a code block and a new scope. Class members and the body of a method are examples of what can live inside these braces in various contexts.

Inside of method bodies you can use the braces to create new scopes like so:

void doSomething()
{
    int a;

    {
        int b;
        a = 1;
    }

    a = 2;
    b = 3; //Will fail because the variable is declared in an inner scope.
}

Program structure

[edit]

A C# application is consisting of classes and their members. Classes and other types exist in namespaces but can also be nested inside other classes.

Main-method

[edit]

Whether it is a console or a graphical interface application the program must have an entrypoint of some sort. The entrypoint of the C# application is the Main-method. There can only be one and it is a static method which is situated in a class. The method usually returns void and can pass command-line arguments as an array of strings.

static void Main(string[] args)
{
}

A Main-method is also allowed to return an integer value if specified.

static int void Main(string[] args)
{
    return 0;
}

Namespaces

[edit]

Namespaces are a part of a type name and they are used to group and/or distinguish names entities from other ones.

    System.IO.DirectoryInfo //DirectoryInfo is in the System.IO-namespace

A namespace is defined like this:

namespace FooNamespace
{
    //Members
}

using-statement

[edit]

The using-statement loads a specific namespace from a referenced assembly. It is usually placed in the top (or header) of a code file but it can be placed elsewhere if wanted. Like for instance inside classes.

using System;
using System.Collections;

You can also use the statement to define another name for an existing type. This can simplify your code.

using DirInfo = System.IO.DirectoryInfo;

Operators

[edit]
Operator category Operators
Arithmetic + - * /  %
Logical (boolean and bitwise) & | ^  ! ~ && || true false
String concatenation +
Increment, decrement ++ --
Shift << >>
Relational ==  != < > <= >=
Assignment = += -= *= /=  %= &= |= ^= <<= >>=
Member access .
Indexing [ ]
Cast ( )
Conditional ?  :
Delegate concatenation and removal + -
Object creation new
Type information as is sizeof typeof
Overflow exception control checked unchecked
Indirection and Address * -> [] &

Operator overloading

[edit]

Some of the existing operators can be overloaded by writing an overload method.

public static Foo operator+(Foo foo, Bar bar)
{
    return new Foo(foo.Value + bar.Value)
]

These are the overloadable operators:

Operators
+, -, !, ~, ++, --, true, false Unary operators
+, -, *, /, %, &, |, ^, <<, >> Binary operators
==, !=, <, >, <=, >= Comparison operators - must be overloaded in pairs.
  • Assignment operators (+=, *= etc.) are combinations of a binary operator and the assignment operator (=) and will be evaluated using the ordinary operators, which can be overloaded.
  • Cast operators (( )) cannot be overloaded, but you can define conversion operators.
  • Array indexing ([ ]) operator is not overloadable, but you can define new indexers.

See also

Conversion operators

[edit]

The cast operator is not overloadable but you can write a conversion operator method which lives in the target class. Conversion methods can define two varieties of operators, implicit and explicit conversion operators. The implicit operator will cast without specifying with the cast operator (( )) and the explicit operator requires it to be used.

Implicit conversion operator

class Foo
{
    public int Value;
    public static implicit operator Foo(int value)
    {
        return new Foo(value)
    ]
}
//Implicit conversion
Foo foo = 2;

Explicit conversion operator

class Foo
{
    public int Value;
    public static explicit operator Foo(int value)
    {
        return new Foo(value)
    ]
}
//Explicit conversion
Foo foo = (Foo)2;

Null-Coalesce operator

[edit]

Control structures

[edit]

Conditional structures

[edit]

If statement

[edit]

Simple one-line statement:

if(i == 3) ... ;

Multi-line with else-block (without any braces):

if(i == 2)

    ...

else

    ...

Recommended coding conventions for an if-statement.

if(i == 3)
{
    ...
}
else if(i == 2)
{
    ...
}
else
{
    ...
}

Switch statement

[edit]
switch(ch)
{
    case 'A':
        ...
        break;

    case 'B':
    case 'C':
         ...
         break;

    default:
        ...
        break;
}

Iteration structures

[edit]

Iteration statements are statements that are repeatedly executed when a given condition is evaluated as true.

While loop

[edit]
while(i == true)
{
    ...
}
Do... while
[edit]
do
{
    ...
}
while(int i in intList)

For loop

[edit]
for(int i = 0; i < 10; i++)
{
    ...
}

For-each loop

[edit]

The for-each statement is derived from the for-statement and uses the built-in iterators over arrays and collections.

Each item in the give collection will be returned and reachable in the context of the code block. When the block has been executed the next item will be returned until there are no left.

foreach(int i in intList)
{
    ...
}

Jump statements

[edit]

Labels and Goto statement

[edit]

Labels are given points in code that can be jumped to by using the goto statement.

start:
    ...
    goto start;

Break statement

[edit]

The break breaks out of all control statements.

int e = 10;
for(int i=0; i < e; i--)
{
    while(true)
    {
        break;
    }
}
//Will break to this point.

Continue statement

[edit]

The break breaks out of the current control statement.

int e = 10;
for(int i=0; i < e; i--)
{
    while(true)
    {
        break;
    }

    //Will break to this point.
}

Types

[edit]

C# is a strongly-typed language just like its predecessors C and C++. That means that every variable and constant get a fixed type when they are being declared. There are two kinds of types: value types and reference types.

Value types

[edit]

Structs

[edit]

Structures are more commonly known as structs. Structs are user-defined value types that are declared using the struct keyword. They are very similar to classes but are more suitable for lightweight types. Some important syntactical differences between a class and a struct are presented later in this article.

struct Foo
{
    ...
}

The primitive data types are all structs.

Pre-defined types
[edit]
Primitive Types
Type Name BCL Equivalent Value Range Size Default Vadier
sbyte System.SByte integer -128 through 127 8-bit (1-byte) 0
short System.Int16 integer -32,768 through 32,767 16-bit (2-byte) 0
int System.Int32 integer -2,147,483,648 through 2,147,483,647 32-bit (4-byte) 0
long System.Int64 integer -9,223,372,036,854,775,808 through 9,223,372,036,854,775,807 64-bit (8-byte) 0
byte System.Byte unsigned integer 0 through 255 8-bit (1-byte) 0
ushort System.UInt16 unsigned integer 0 through 65,535 16-bit (2-byte) 0
uint System.UInt32 unsigned integer 0 through 4,294,967,295 32-bit (4-byte) 0
ulong System.UInt64 unsigned integer 0 through 18,446,744,073,709,551,615 64-bit (8-byte) 0
decimal System.Decimal signed decimal number -7.9228162514264337593543950335 through 7.9228162514264337593543950335 128-bit (16-byte) 0.0
float System.Single floating point number -3.402823E+38 through 3.402823E+38 32-bit (4-byte) 0.0
double System.Double floating point number -1.79769313486232E+308 through 1.79769313486232E+308 64-bit (8-byte) 0.0
bool System.Boolean Boolean true or false 8-bit (1-byte) False
char System.Char single Unicode character 16-bit (2-byte) -

Note: string (System.String) is not a struct and does not count as a primitive.

Enumerations

[edit]

Enumerated types (enums) are types containg a names that represents integral values.

enum Season
{
    Winter = 0,
    Spring = 1,
    Summer = 2,
    Autumn = 3,
    Fall = Autumn    //Autumn is called Fall in American English.
}

Enums-instances are declared as ordinary variables and they get the default value 0. You can later assign the values contained in the declared enumeration type.

Season season;
season = Season.Spring;

You can increment and decrement enum-variable to get another value.

season++; //Season.Spring (1) becomes Season.Summer (2).
season--;

See also

Reference types

[edit]

Arrays

[edit]
int[] numbers = new int[5];
number[0] = 2;
number[1] = 5;
int x = number[0];
Initializers
[edit]
//Long syntax
int[] numbers = new int[5]{ 20, 1, 42, 15, 34 };
//Short syntax
int[] numbers2 = { 20, 1, 42, 15, 34 };
Multidimensional arrays
[edit]
int[,] numbers = new int[3, 3];
number[1,2] = 2;

Classes

[edit]

Classes are self-describing used-defined reference types.

String class
[edit]

The String class represents an immutable sequence of unicode characters (char).

Interface

[edit]

Interfaces are data structures that contains member definitions and not an actual implementation. They are useful when you want to define a contract between members in different types that has different implementations. You can declare definitions for methods, properties and indexers. These must be implemented by a class as public members.

interface IBinaryOperation
{
    double A { get; set; }
    double B { get; set; }

    double GetResult(double a, double b);
}

Delegate

[edit]

C# provides type-safe object-oriented function pointers in the form of delegates.

 delegate int Operation(int a, int b); Operation addition;  int Add(int i1. int i2) {     return a + b; }   addition += Add;   //Calling the delegate. int result = addition(2, 3);

Initializing the delegate with an anonymous method.

  additon = delegate(int a, int b){ return a + b; };´

See also

Events

[edit]

Events are pointers that can point to multiple methods. More exactly they bind method pointers to one identifier. This can therefor be seen as an extension to delegates. They are typically used as triggers in UI development.

They are declared like so:

// event [delegate] [name]
event MouseEventHandler OnClick;

This is how they are used:

delegate void MouseEventHandler(object sender, MouseEventArgs e)


void OnClick(object sender, MouseEventArgs e)
{
    Console.WriteLine("Clicked!");
}


//Define an event in a class
event MouseEventHandler OnClick;

//Bind a event handler method to the event.
OnClick += OnClick;


//Old syntax
OnClick += new MouseEventHandler(OnClick);

//Trigger the event from code
OnClick(this, new MouseEventArgs());

See also

Nullable types

[edit]
This is a feature of C Sharp 2.0.

Enables value types to allow the value null to be assigned to them.

int? n = 2;
n = null;

Pointers

[edit]

C# has and allows pointers to value types (primitives, enums and structs) in unsafe context: methods and codeblock marked unsafe. These are syntactically the same as pointers in C and C++. However, runtime-checking is disabled inside unsafe-blocks.

void main(string[] args)
{
    unsafe
    {
        int* a = 2;
        int* b = &a;

        Console.WriteLine("Address of *a: {0}. Value: {1}", &a, a);
        Console.WriteLine("Address of *b: {0}. Value: {1}", &b, b);

        // Will give the same address and value.
    }
}

See also

Dynamic

[edit]
This is a future feature of C Sharp 4.0 and .NET Framework 4.0.

Type dynamic is a feature that enables dynamic runtime lookup to C# in a static manner. Dynamic is a static "type" which exists at runtime.

dynamic x = new Foo();
x.DoSomething();  //Will compile and resolved at runtime. An exception will be cast if invalid.

Boxing and unboxing

[edit]

Boxing is the operation of converting a value of a value type into a value of a corresponding reference type.[1] Boxing in C# is implicit.

Unboxing is the operation of converting a value of a reference type (previously boxed) into a value of a value type.[1] Unboxing in C# requires an explicit type cast.

Example:

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

Object-oriented programming (OOP)

[edit]

C# is a object-oriented programming language.

See also

Objects

[edit]

An object is created with the type as a template and is called an instance of that particular type.

In C# objects are either references or values. No further distinction is made between those in code.

Object class

[edit]

All types, even value types in their boxed form, implicitly inherit from the System.Object class which is the ultimate base class of all objects. The class contains the most common methods shared by all objects. Some of these are virtual and can be overridden.

Some of the members:

  • Equals - Supports comparisons between objects.
  • Finalize - Performs cleanup operations before an object is automatically reclaimed. (Default destructor)
  • GetHashCode - Generates a number corresponding to the value of the object to support the use of a hash table.
  • GetType - Gets the Type of the current instance.
  • ToString - Manufactures a human-readable text string that describes an instance of the class

Classes

[edit]

Classes are fundamentals of an object-oriented language such as C#. They serve as a template for objects. They contain members that store and manipulate data in real-life-like way.

See also

Differences between classes and structs

[edit]

Although classes and structures are similar in both the way they are declared and how they are used there are some significant differences. Classes are reference types and structs value types. A structure is allocated on the stack when it is declared and the variable is bound to its address. It directly contains the value. Classes are different because the memory is allocated as objects on the heap. Variables are rather managed pointers on the stack which points to the objects. They are references.

Structures requires some more than classes. For example you need to explicitly create a default constructor which takes no arguments to initialize the struct and its members. The compiler will create a default one for classes. All fields and properties of as struct must have been initialized before an instance is created. Structs does not have finalizers and cannot inherit from another class like classes do. But they inherit from System.ValueType, that inherits from System.Object. Structs are more suitable for smaller constructs of data.

This is a short summary of the differences:

Default constructor Finalizer Member initialization Inheritance
Classes not required (auto generated) yes not required yes (if base class is not sealed)
Structs required (not auto generated) no required not supported

Declaration

[edit]

A class is declared like so:

class Foo
{
    //Member declarations
}


Partial class
[edit]
This is a feature of C Sharp 2.0.

A partial class is a class declaration whose code is divided into separate files. The different parts of a partial class must be marked with keyword partial.

//File1.cs
partial class Foo
{
    ...
}

//File2.cs
partial class Foo
{
    ...
}

Initialization

[edit]

Before you can use the members of the class you need to initialize the variable with a reference to a object. To create on you call the appropriate constructor using the new keyword. It has the same name as the class.

Foo foo = new Foo();

For structs it is optional to explicitly call a constructor because the default one is called automatically. You just need to declare it and it gets initialized with standard values.

Object initializers
[edit]
This is a feature of C Sharp 3.0.

Provides a more convenient way of initializing public fields and properties of an object. Constructor calls are optional when there is a default constructor.

Person person = new Person {
    Name = "John Doe",
    Age = 39
};

//Equal to
Person person = new Person();
person.Name = "John Doe";
person.Age = 39;
Collection initializers
[edit]
This is a feature of C Sharp 3.0.

Collection initializers give an array-like syntax for initializing collections. The compiler will simply generate calls to the Add-method. This works for classes that implement the interface ICollection.

List<int> list = new List<int> {2, 5, 6, 6 };

//Equal to
List<int> list = new List<int>();
list.Add(2);
list.Add(5);
list.Add(6);
list.Add(6);

Accessing members

[edit]

Members of both instances and static classes are accessed with the . operator.

Accessing an instance member
Instance members can be accessed through the name of a variable.

string foo = "Hello";
string fooUpper = foo.ToUpper();

Accessing a static class member
Static members are accessed by using the name of the class or any other type.

int r = String.Compare(foo, fooUpper);


Modifiers

[edit]

Modifiers are keywords used to modify declarations of types and type members. Most notably there is a sub-group containing the access modifiers.

  • abstract - Specifies that a class only serves as a base class. It must be implemented in an inheriting class.
  • const - Specifies that a variable is a constant value that have to be initialized when it is declared.
  • event - Declare an event.
  • extern - Specify that a method signature without a body us a DLL-import.
  • override - Specify that a method or propery declaration is an override of a virtual member or an implementation of a member of an abstract class.
  • readonly - Declare a field that can only be assigned values as part of the declaration or in a constructor in the same class.
  • sealed - Specifies that a class cannot be inherited.
  • static - Specifices that a member belongs to the class and not to a specific instance. (see section static)
  • unsafe -
  • virtual
  • volatile -
Access modifiers
[edit]

The access modifiers set the accessibility of classes, methods and other members. Something marked public can be reached from anywhere. private members can only be accessed from inside of the class they are declared inand will be hidden when inherited. Members with the protected modifier will be private but accessible when inherited. internal classes and members will only be accessible from the inside of the declaring assembly.

Classes and members are implicitly private if they do not have an access modifier.

public class Foo
{
    public int Do()
    {
        return 0;
    }

    public class Bar
    {

    }
}
Classes Members (incl. Nested types)
public yes yes
private yes yes
protected no yes
internal yes yes
static
[edit]

The static defines that a member belongs to the class and not a specific object. Classes marked static are only allowed to contain static members. Static members are sometimes referred to as class members.

public class Foo
{
    public static void Something()
    {
        ...
    }
}
//Calling the class method.
Foo.Something();

Constructors

[edit]

A constructor is a special method that is called when a object is going to be initialized. Its purpose is to initialize the members of the object. The main differences between constructors and ordinary methods are that constructors are named after the class and does not return anything. They may take parameters as any method.

class Foo
{
    Foo()
    {
        ...
    }
}

Constructors can be public, private or internal.

See also

Destructor

[edit]

The destructor is called when the object is being collected by the garbage collector to perform some manual clean-up. There is a default destructor method called finalize that can be overridden by declaring your own.

The syntax is similar to the one of constructors. The difference is that the name is preceded by a ~ and it cannot contain any parameters. There cannot be more than one destructor.

class Foo
{
    ...

    ~Foo()
    {
        ...
    }
}

Finalizers are always private.

See also

Methods

[edit]
class Foo
{
    int Bar(int a, int b)
    {
        return a % b;
    }
}

You simply call the method by using . .

Foo foo = new Foo();
int r = foo.Bar(7, 2)

Console.WriteLine(r);

See also

Method overloading
[edit]
ref and out parameters
[edit]

You can explicitly make arguments be passed by reference when calling a method with parameters preceded by keywords ref or out. These managed pointers comes in handy when passing value type variables that you want to be modified inside the method by reference. The main difference between the two is that an out-parameter must be assigned when the method returns.

void PassRef(ref x)
{
    if(x == 2) x = 10;
}
int Z;
PassRef(ref Z);


void PassOut(out x)
{
    x = 2;
}
int Q;
PassOut(out Q);
Optional parameters
[edit]
This is a future feature of C Sharp 4.0.

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(ref 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 interoperating with COM easier. Previously, C# had 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);
extern
[edit]

A feature of C# is the abillity to call native code. You simply declare a method signature without a body and mark it as extern. You also need to add the DllImport-attribute to reference the DLL-file you want .

[DllImport("win32.dll")]
static extern double Pow(double a, double b);

Fields

[edit]

Fields, or class variables, can be declares inside the class body to store data. It is considered good practice to keep a field private and declare a property to access it.

class Foo
{
    double foo;
}


Fields can initialized directly when declared.

class Foo
{
    double foo = 2.3;
}


Modifiers for fields:

  • static - Makes the field a static member.
  • readonly - Allows the field to be initialized only once in a constructor.
  • const - Makes the field a constant.
  • public - Makes the field public.
  • private - Makes the field private.
  • protected - Makes the field protected.

Properties

[edit]

Properties bring field-like syntax and combine them with the power of methods. A property can have two accessors: get and set.

class Person
{
    string name;

    string Name
    {
        get { return name; }
        set { name = value; }
    }
}

//Using a property
Person person = new Person();
person.Name = "Robert";

Modifiers for properties:

  • static - Makes the property a static member.
  • public - Makes the property public.
  • private - Makes the property private.
  • protected - Makes the property protected.


Modifiers for property accessors:

  • public - Makes the accessor public.
  • private - Makes the accessor private.
  • protected - Makes the accessor protected.


Automatic properties
[edit]
This is a feature of C Sharp 3.0.

A feature of C# 3.O is auto-implemented properties. You define accessors without bodies and the compiler will generate a backingfield and the necessary code for the accessors.

double Width
{
    get;
    private set;
}

Indexers

[edit]

Indexers add array-like indexing capabilities to objects. They are implemented in a way similar to properties.

class IntList
{
   int[] items;

   int this[int index]
   {
        get { return this.items[index]; }
        set { this.items[index] = value; }
    }
}

//Using an indexer
IntList list = new IntList();
list[2] = 2;

Inheritance

[edit]

Classes in C# may only inherit from one classes. A class may derive from any class that is not marked as sealed.

class A
{

}

class B : A
{

}

See also

virtual
[edit]

Methods marked virtual provide an implementation but it can be overridden by the inheritors by using the override-keyword.

class Operation
{
    public virtual int Do()
    {
        return 0;
    }
}

class NewOperation
{
    public override int Do()
    {
        return 1;
    }
}
abstract
[edit]

Abstract classes are classes that only serve as templates and you can not initialize a object of that type. Otherwise it is just like an ordinary class.

There may be abstract members too. Abstract members are members of abstract classes that do not have any implementation. They must be overridden by the class that inherits the member.

abstract class Mammal
{
    public abstract void Walk();
}

class Human : Mammal
{
    public override void Walk()
    {

    }

    ...
}
sealed
[edit]

The sealed modifier can be combined with the others as an optional modifier for classes to make them in-inheritable.

internal sealed class _FOO
{

}

Interfaces

[edit]

Interfaces are data structures that contains member definitions and not an actual implementation. They are useful when you want to define a contract between members in different types that has different implementations. You can declare definitions for methods, properties and indexers. These must be implemented by a class as public members.

interface IBinaryOperation
{
    double A { get; set; }
    double B { get; set; }

    double GetResult(double a, double b);
}

Implementing an interface

[edit]

An interface is implemented by a class or extended by another interface in the same way you derive a class from another class using the :-notation.

public class Adder : IBinaryOperation
{
    double A { get; set; }
    double B { get; set; }

    double GetResult(double a, double b)
    {
        return a + b;
    }
}

Note: The properties in the class that extends IBinaryOperation are auto-implemented by the compiler. Both gets a backingfield.

Here is a interface that extends two interfaces.

interface IInterfaceC : IInterfaceA, IInterfaceB
{
    ...
}

Generics

[edit]
This is a feature of C Sharp 2.0 and .NET Framework 2.0.

Generics, or parameterized types, orparametric 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.[2]

See also

Type-parameters

[edit]

Type-parameters are names used in place of concrete types when defining a new generic. They may be associated with classes or methods by placing the type parameter in angle brackets < >. When instantiating (or calling) a generic, you can then substitute a concrete type for the type-parameter you gave in its declaration. Type paremeters may be constrained by use of the where keyword and a constraint specification, any of the six comma separated constraints may be used:

Constraint Explanation
where T : struct type parameter must be a value type
where T : class type parameter must be a reference type
where T : new() type parameter must have a constructor with no parameters (must appear last)
where T : <base_class> type parameter must inherit from <base_class>
where T : <interface> type parameter must be, or must implement this interface
where T : U naked type parameter constraint

Covariance and contravariance

[edit]
This is a future feature of C Sharp 4.0 and .NET Framework 4.0.

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)
  {
    System.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 are extended from Base. It makes it possible to write code such as:

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

See also

Generic types

[edit]

Generic classes

[edit]

Classes and structs can be generic.

public class List<T>
{
    ...
    public void Add(T item)
    {
         ...
    }
}

List<int> list = new List<int>();
list.Add(6);
list.Add(2);

Generic interfaces

[edit]
interface IEnumerable<T>
{
    ...
}

Generic delegates

[edit]
delegate R Func<T1, T2, R>(T1 a1, T2 a2);

Generic methods

[edit]

Enumerators

[edit]

An enumerator is an iterator. Enumerators are typically obtained by calling the GetEnumerator() method of an object implementing theIEnumerable interface. Container classes typically implement this interface. However, the foreach statement inC# can operate on any object providing such a method, even if it doesn't implementIEnumerable. Both interfaces were expanded into generic versions in .NET 2.0.

The following shows a simple use of iterators in C# 2.0:

// explicit version
IEnumerator<MyType> iter = list.GetEnumerator();
while (iter.MoveNext())
    Console.WriteLine(iter.Current);

// implicit version
foreach (MyType value in list)
    Console.WriteLine(value);

Generator functionality

[edit]
This is a feature of C Sharp 2.0.

The .NET 2.0 Framework allowed C# to introduce an iterator that provides generatorfunctionality, using a yield return construct similar to yield in Python.[3] With a yield return, the function automatically keeps its state during the iteration.

// 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;
    }
}

LINQ

[edit]
This is a feature of C Sharp 3.0 and .NET Framework 3.0.
Main article: LINQ

LINQ, short for Language Integrated Queries, is a .NET Framework feature which simplifies the handling of data. Mainly it adds support that allows you to query arrays, collections and databases. It also introduces binders that makes it easier to access to databases and their data.

Query syntax

[edit]

The LINQ query syntax was introduces C# 3.0 and let you write SQL-like queries in C#.

var list = new List<int>{ 2, 7, 1, 3, 9 };

var result = from i in list
               where i > 1
               select i;

The statements are compiled into method calls on the object of the type that ultimately must implementIQueryable<T>.

Anonymous methods

[edit]

Anonymous methods, or in their present form more commonly referred to as "lambda expressions", is a feature which allows you to write inline closure-like functions in your code.

There are various of ways to create anonymous methods. Prior to C# 3.0 there was limited support by using delegates.

See also

Anonymous delegates

[edit]
This is a feature of C Sharp 2.0.

Anonymous delegates are declared in code.

Func<int, int> f = delegate(int x) { return x * 2; };

Lambda expressions

[edit]
This is a feature of C Sharp 3.0.

Lambda expressions provide a simple syntax for inline functions that are similar to closures. Functions with parameters infer the type of the parameters if other is not explicitly specified.

// [arguments] => [method-body]

//With parameters
n => n == 2;
a, b => a + b;

//With explicitly typed parameters
int a, int b => a + b;

//No parameters
() => return 0;

//Assigning lambda to delegate
Func<int, int, int> f = (a, b) => a + b;

Alternative syntax:

(a, b) => { a + b }

Lambda expressions can be passed as arguments in method calls.

var list = stringList.Where(n => n.Lenght > 2);

Lambda expression are essentially compiler generated methods that are passed via delegates.

Anonymous types

[edit]
This is a feature of C Sharp 3.0.

Anonymous types are nameless classes that are generated by the compiler. They are only consumable and yet very useful in a scenario like where you have a LINQ query which returns an object on select and you just want to return some specific values. Then you can define a anonymous type containing auto-generated read-only fields for the values.

When instantiating another anonymous type declaration with the same signature the type is automatically inferred by the compiler.

var carl = new { Name = "Carl", Age = 35 }; //Name of the type is only known by the compiler.
var mary = new { Name = "Mary", Age = 22 }; //Same type as the expression above

Extension methods

[edit]
This is a feature of C Sharp 3.0.

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);


See also


Miscellaneous

[edit]

Attributes

[edit]

Attributes are entities of data that is stored as metadata in the compiled assembly. An attribute can be added to types and members like properties and methods.

[CompilerGenerated]
public class $AnonymousType$120
{   
    [CompilerGenerated]
    public string Name { get; set; }
}

The .NET Framework comes with predefined attributes that can be used. Some of them serve an important role at runtime while some is just for syntactic decoration in code like CompilerGenerated. It does only mark that it is a compiler generated element. You can create your own if needed and/or wanted.

An attribute is essentially a class which inherits from the System.Attribute class. By convention attribute classes end with "Attribute" in their name. This will not be required when using it.

public class EdibleAttribute : Attribute
{
    public Edible() : base()
    {

    }

    public Edible(bool isPoisnous)
    {
        this.IsPoisonous = isPoisonous;
    }

    public bool IsPoisonous { get; set; }
}

Showing the attribute in use using the optional constructor parameters.

[Edible(true)]
public class Peach : Fruit
{
   //Members if any
}

Preprocessor

[edit]

C# features "preprocessor directives"[4] (though it does not have an actual preprocessor) based on the C preprocessor that allow programmers to define symbolsbut 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

[edit]

C# utilizes a double forward slash (//) to indicate the rest of the line is a comment.

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

Multi-line comments can 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

[edit]

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 documentation 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 documentation comments, while defined in the version 1.0 language specification, were not supported until the .NET 1.1 release.[5] These comments are designated by a starting forward slash/asterisk/asterisk (/**) and ending asterisk/forward slash (*/).[6]

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 are 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:[6]

/**
 * <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.

Dialects

[edit]

Spec#

[edit]
Main article: Spec Sharp

Spec# is the name of a syntactic extension and a possible future feature to the C# language. It adds syntax for the code contracts API that is going to be introduced in .NET Framework 4.0. Spec# is being developed by Microsoft Research.

This example shows two of the basic structures that is used when adding contracts to your code.

    static void Main(string![] args)
        requires args.Length > 0
    {
        foreach(string arg in args)
        {
            Console.WriteLine(arg);
        }
    }
  • ! is used to make a reference type non-nullable, e.g. you cannot set the value to null. This in contrast of nullable types which allows value types to be set as null.
  • requires indicates a condition that must be followed in the code. In this case the length of args is not allowed to be zero or less.

See also

[edit]
[edit]
  1. ^ a b Cite error: The named reference insidecsharpp2ch4 was invoked but never defined (see the help page).
  2. ^ "An Introduction to C# Generics". Microsoft. 2005. Retrieved June 18, 2009. {{cite web}}: Unknown parameter |month= ignored (help)
  3. ^ "yield". C# Language Reference. Microsoft. Retrieved 2009-04-26.
  4. ^ "C# Preprocessor Directives". C# Language Reference. Microsoft. Retrieved June 18, 2009.
  5. ^ Horton, Anson (2006-09-11). "C# XML documentation comments FAQ". Retrieved 2007-12-11.
  6. ^ a b "Delimiters for Documentation Tags". C# Programmer's Reference. Microsoft. January 1, 1970 GMT. Retrieved June 18, 2009. {{cite web}}: Check date values in: |date= (help)