Синтаксис языка C Sharp

В этой статье описывается синтаксис языка C#. Описываемый синтаксис полностью совместим с синтаксисом языка C# в .Net Framework и Mono.

Основы

Идентификаторы

Идентификатор — это имя сущности в коде. Существует стандарт именования идентификаторов, который следует использовать в коде. Идентификатор может:

  • Начинаться с символа «_».
  • Содержать заглавные и строчные буквы в формате Unicode. Регистр имеет значение.
  • Начинаться с символа "@".

Идентификатор не может:

  • Начинаться с цифры.
  • Начинаться с символа, если это ключевое слово.
  • Содержать более 511 символов.
Ключевые слова

Ключевые слова — это предварительно определенные зарезервированные идентификаторы, имеющие особое синтаксическое значение. Язык имеет два типа ключевых слов — зарезервированные в любой части кода и контекстные. Слова первого типа, например false или byte, могут быть использованы только как ключевые слова. Слова второго типа, например слово where, имеют особое значение только в определённом контексте и могут быть использованы в качестве идентификаторов вне него.[MSDN 1] Если всё же необходимо использовать ключевое слово в качестве идентификатора, то необходимо объявить его с помощью префикса @ — например, @byte.[MSDN 1]

Ключевые слова C#
abstract as base bool
break byte case catch
char checked class const
continue decimal default delegate
do double else enum
event explicit extern false
finally fixed float for
foreach goto if implicit
in[MSDN 2] in (универсальный модификатор)[MSDN 3] int interface
internal is lock long
namespace new null object
operator out[MSDN 4] out (универсальный модификатор)[MSDN 5] override
params private protected public
readonly ref return sbyte
sealed short sizeof stackalloc
static string struct switch
this throw true try
typeof uint ulong unchecked
unsafe ushort using virtual
void volatile while  
Контекстные ключевые слова C#
add dynamic from get
global group into join
let orderby partial (тип)[MSDN 6] partial (метод)[MSDN 7]
remove select set value
var where (ограничение универсального

типа)[MSDN 8]

where (предложение запроса)[MSDN 9] yield

Примеры:

string @out; //Чтобы дать идентификатору имя, идентичное ключевому слову, необходимо использовать префикс @
string идентификатор; //C# поддерживает Юникод и допускает именование идентификаторов с помощью любых символов Юникода
string var {get; set;}; //Здесь не требуется использовать префикс @ т.к. var - контекстное ключевое слово

public void function()
{
    var s = ""; //Для того, чтобы компилятор автоматически определял тип переменной, используется ключевое слово var
}

Литералы

Целочисленные
Шестнадцатеричные 0xF5, 0x[0..9, A..F, a..f]+
Десятичные 245, [0..9]+
Числа с плавающей запятой
одинарной точности 23.5F, 23.5f; 1.72E3F, 1.72E3f, 1.72e3F, 1.72e3f
двойной точности 23.5, 23.5D, 23.5d; 1.72E3, 1.72E3D, ...
Даты
дата Не поддерживаются
Символы
символ 'a', 'Z', '\u0231'
Строки
строка "Hello, world"
"C:\\Windows\\", @"C:\Windows\"
Экранирующие символы[1]
код символа Unicode \u после чего следует код символа
символ табуляции \t
Backspace \b
возврат каретки \r
разрыв страницы \f
обратный слеш \\
одинарная кавычка \'
двойная кавычка \"
перевод строки \n

Переменные

Переменная — это идентификатор, содержащий какое-либо значение. Переменная определяется типом и именем, а также может инициализироваться при объявлении. Объявлять переменные можно только внутри функций.

Объявление
int variable; //Объявление неинициализированной переменной целочисленного типа с именем variable
Инициализация
int variable; //Объявление неинициализованной переменной
variable = 1; //Инициализация переменной
Объявление и инициализация
int variable = 1; //Одновременное объявление и инициализация переменной

Можно объявить сразу несколько переменных одного типа:

int a, b;
int a = 2, b = 3;

Неявный тип

Введено в C# 3.0

Если компилятор может определить тип переменной при инициализации, его можно опустить, заменив ключевым словом var :

var chars = new char[] {'A', 'O'}; //преобразуется компилятором в char[] chars = new char[] {'A', 'O'};
var numbers = new List<int>(); //преобразуется компилятором в List<int> numbers = new List<int>();

См. также

Константы

Константа — это идентификатор, содержащий значение, которое запрещено менять во время выполнения программы. Константы неявно статические.

const

Локальная переменная или свойство с заданным значением могут быть объявлены с ключевым словом const, после чего их значение не может быть изменено.

class Foo
{
    const double PI = 3.1415;

    Foo()
    {
        const int countOfPlanets = 9;
    }
}

readonly

Свойство, объявленное с ключевым словом readonly, также, как и константа, не может быть изменено после инициализации. Однако, в отличие от поля с ключевым словом const, оно может быть инициализированно в конструкторе.

class Foo
{
    readonly int a = 3;
    readonly string b;
    readonly StringBuilder builder;

    Foo()
    {
        b = "String";
        builder = new StringBuilder();
    }
}

Блоки кода

Операторы {...} используются для обозначения начала и конца блоков кода, а также обозначения области видимости. Идентификатор, объявленный внутри фигурных скобок, видим только внутри них и во вложенных областях видимости. Следующий пример демонстрирует работу блока кода и областей видимости:

void doSomething()
{
    int a;

    {
        int b;
        a = 0;
    }

    a = 1;
    b = 1; //Здесь компилятор выдаст ошибку, так как переменная b объявлена в области видимости, недоступной для данного кода.
}

Структура программы

Приложения, написанные на C#, состоят из классов и их членов. Классы и другие типы объявляются внутри пространств имён, а также других классов.

namespace FooNamespace
{
    class Foo
    {
        class IncludedClass
        {
        }
    }
}

Пространства имён

Пространство имён является частью имени типа. Используется для того чтобы сгруппировать типы или чтобы различать типы с одним именем, но разными функциями.

System.IO.DirectoryInfo //Класс DirectoryInfo в пространстве имён IO, которое вложено в пространство имён System

Объявляется пространство имён так:

namespace Application
{
    //Члены пространства имен
}

Ключевое слово using

При использовании класса не требуется уточнять его пространство имён, если оно указано в .cs файле с помощью директивы using. Обычно это делается вверху файла с исходным кодом, однако может быть размещено и в других местах, например внутри класса.

using System;
using System.Collections;

Также директива using позволяет создавать псевдонимы пространства имен или типа, например, если его имя слишком длинное:

using Net = System.Net;
using DirInfo = System.IO.DirectoryInfo;

Метод Main

Любое приложение, консольное оно или графическое, обязано иметь точку входа. В C#-приложении такой точкой является метод Main, который может быть только в одном экземпляре и обязательно должен быть статическим. Этот метод может не возвращать значения (ключевое слово void):

static void Main(string[] args)
{
}

…или возвращать целое число, которое является кодом завершения программы: в случае, если программа завершилась без ошибки, этот код — 0.

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

Операторы

Категория операторов Операторы
Арифметические + - * /  %
Логические (булевые и побитовые) & | ^  ! ~ && ||
Конкатенация строк +
Приращение, уменьшение ++ --
Сдвиг << >>
Сравнение ==  != < > <= >=
Присвоение = += -= *= /=  %= &= |= ^= <<= >>=
Доступ к членам .
Индексирование [ ]
Приведение типов ( )
Условные ?  :
Создание объекта new
Информации о типе as is sizeof typeof
Проверка переполнения checked unchecked
Работа с указателями * -> [] &

Перегрузка операторов

Некоторые операторы могут быть перегружены. Для перегрузки оператора необходимо определить статическую функцию, у которой имя состоит из ключевого слова operator и собственно самого оператора. Для унарных операторов функция должна иметь один параметр, для бинарных и операторов сравнения — два. В обоих случаях один из параметров должен иметь тот же тип, что и класс или структура, его объявившие.

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

Список перегружаемых операторов:

Операторы
Унарные операторы + - ! ~ ++ -- true false
Бинарные операторы + - * / % & | ^ << >>
Операторы сравнения

могут быть перегружены только попарно

== != < > <= >=
  • Операторы присваивания (+=, *= и др.) нельзя перегрузить, но они являются компинацией оператора (=) и одного из бинарных операторов, а бинарные операторы можно перегрузить.
  • Оператор приведения типа (( )) не может быть перегружен, но вы можете определить новые операторы преобразования с помощью explicit и implicit.
  • Оператор индексирования массива ([ ]) нельзя перегрузить, но можно определить новые индексаторы.

См. также

Операторы преобразования и приведения типа

Оператор приведения типа не может быть перегружен, однако вы можете определить операторы явного преобразования (приведения типа) — explicit и неявного преобразования — implicit. Они различаются тем, операторы неявного преобразования не должны генерировать исключения и должны обеспечить сохранность информации.[MSDN 10]. Для явного преобразования необходимо использовать оператор ( ), для неявного — нет.

Оператор неявного преобразования

class Foo
{
    public string Value;
    public static implicit operator Foo(string value)
    {
        return new Foo(value)
    }
}
//Неявное преобразование
Foo foo = "Example";

Оператор явного преобразования

class Foo
{
    public string Value;
    public static explicit operator Foo(string value)
    {
        if (value.IsNullOrEmpty()) throw new ArgumentException("String can not be null or empty!");
        return new Foo(value)
    }
}
//Явное преобразование
Foo foo = (Foo)"Example";
Foo fooNull = (Foo)""; //Ошибка

Оператор as

Оператор as является оператором приведения типа. Если преобразование типа возможно, оператор вернёт объект указанного типа, в противном случае он вернёт null.

Stream stream = File.Open(@"C:\Temp\data.dat");
FileStream fstream = stream as FileStream; //Will return an object.

String str = stream as String; //Will fail and return null.

Оператор ??

Введено в C# 2.0

Если значение левой переменной равно null, то будет возвращено значение правой переменной, в противном случае будет возвращено значение левой переменной.

Следующий код

return ifNotNullValue ?? otherwiseValue;

эквивалентен

return ifNotNullValue == null ? otherwiseValue : ifNotNullValue;

Примечания

Статьи на MSDN
  1. 1 2 Ключевые слова C#. Дата обращения: 4 января 2011. Архивировано 13 декабря 2010 года.
  2. foreach, in. Дата обращения: 4 января 2011. Архивировано 13 декабря 2010 года.
  3. in (универсальный модификатор). Дата обращения: 4 января 2011. Архивировано 5 августа 2010 года.
  4. Модификатор параметров out. Дата обращения: 4 января 2011. Архивировано 15 декабря 2010 года.
  5. out (универсальный модификатор). Дата обращения: 4 января 2011. Архивировано 15 декабря 2010 года.
  6. Разделяемый (тип). Дата обращения: 4 января 2011. Архивировано 15 декабря 2010 года.
  7. Разделяемый (метод). Дата обращения: 4 января 2011. Архивировано 15 декабря 2010 года.
  8. where (ограничение универсального типа). Дата обращения: 4 января 2011. Архивировано 15 декабря 2010 года.
  9. Предложение where. Дата обращения: 4 января 2011. Архивировано 15 декабря 2010 года.
  10. implicit. Дата обращения: 6 января 2011. Архивировано 3 апреля 2011 года.
Прочее
  1. What character escape sequences are available? Дата обращения: 4 января 2011. Архивировано 28 мая 2010 года.