Синтаксис языка 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 |
пробел | \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
Локальная переменная или свойство с заданным значением могут быть объявлены с ключевым словом const, после чего их значение не может быть изменено.
class Foo
{
const double PI = 3.1415;
Foo()
{
const int countOfPlanets = 9;
}
}
readonly
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
using
При использовании класса не требуется уточнять его пространство имён, если оно указано в .cs файле с помощью директивы using. Обычно это делается вверху файла с исходным кодом, однако может быть размещено и в других местах, например внутри класса.
using System;
using System.Collections;
Также директива using
позволяет создавать псевдонимы пространства имен или типа, например, если его имя слишком длинное:
using Net = System.Net;
using DirInfo = System.IO.DirectoryInfo;
Метод Main
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
Оператор 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;