C# 1001 notes
6.51K subscribers
329 photos
9 videos
2 files
313 links
Регулярные короткие заметки по C# и .NET.

Просто о сложном для каждого.

admin - @haarrp
加入频道
Channel created
#basics

№1. Метод Main() и его сигнатура

Стандартной точкой входа для приложений, разработанных на языке C# является статический метод с именем Main.

В большинстве случаев его объявление выглядит следующим образом:

static void Main(string[] args)

Начиная с C# 7.1 появилась возможность объявлять его в асинхронном виде:

static Task<int> Main(string[] args)

@csharp_1001_notes
#basics

№2. Минимально возможная программа на C#

Минимально возможная программа на языке C# будет состоять из класса, содержащего статический метод Main().

using System;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("It's just a start..");
}
}
}

При этом namespace и параметр args так же являются необязательными.

@csharp_1001_notes
#basics

№3. Кто автор языка C#

Язык C# был разработан группой инженеров компании Microsoft для платформы .NET в далёком 2000 году и изначально имел кодовое название COOL (C-style Object Oriented Language).

Главным архитектором является датский инженер-программист Anders Hjelsberg.

C# относится к семье языков с C-подобным синтаксисом, из них его синтаксис наиболее близок к C++ и Java.

@csharp_1001_notes
#basics

№4. Чем C# отличается от Java

Оба языка программирования являются объектно-ориентированными, унаследовали свой синтаксис от языка Си и исполняются в управляемой среде.

Как бы то ни было, между ними есть и различия. Далее основные из них:

🔶 class B extends A равнозначно class B : A

🔶 В Java отсутствуют namespace

🔶 В C# для синхронизации доступа между потоками используется lock, в то время как в Java synchronized

🔶 Наличие в С# модификатора доступа internal

🔶 Перечисления (enum) в Java являются полноценными классами 😲

🔶 C# позволяет использовать строковые литералы в конструкции switch

🔶 Программы на C# используют .NET Framework, в случае с Java это платформа Java SE.

@csharp_1001_notes
#basics

Чем C# отличается от VB .NET

Оба этих языка являются высокоуровневыми и входят в перечень языков программирования для платформы .NET. В основном их отличия синтаксические, но есть и более значительные.

О последних далее:

Есть в C# (нет в VB .NET):

🔶 Указатели и возможность писать unsafe код

🔶 Статические классы

🔶 Контроль переполнения checked/unchecked

🔶 Чувствительность к регистру (case-sensivity)

🔶 Более строгая проверка типов

🔶 Синтаксический сахар (делает язык менее многословным)

Есть в VB .NET (нет в C#):

🔶 XML литералы

🔶 Вспомогательные методы IsNumeric и PMT

🔶 Inline объявление дат, например #12/31/2000#

🔶 Оператор Like для сравнения строки с шаблоном

От себя замечу, что на сегодняшний день большинство проектов, которые продолжают использовать VB .NET являются скорее legacy (требующие сопровождения и исправления ошибок, нежели активной разработки).

C#, напротив, уверенно занял лидерство в качестве основного языка разработки для платформы .NET 😉

💬 Крайне показательным в этом случае являются результаты опроса на StackOverflow за 2018, в котором 34.4% опрошенных указали, что используют C#, в то время как у VB .NET эта цифра едва дотягивает до 6.8%.

@csharp_1001_notes
❇️ Рабочая неделя заканчивается, а значит у нас будет больше времени поломать голову и поразбираться с нюансами языка C#.

Предлагаю вашему внимаю самые 🔥 интересные вопросы этой недели:

🔶 Readonly struct vs classes

🔶 Why is the call ambiguous?

🔶 What happens when creating a variable?

🔶 Random values seem to be not really random?

Всем хороших и плодотворных выходных 👍

#sof_weekly
#basics

Абсолютно минимально возможная программа на C# и Quine

🔶 Ранее в заметке №2 я уже публиковал минимально возможную программу на C#, однако упомянул, что некоторые её части так же опциональны.

Дабы исправить эту оговорку , далее будет действительно самая маленькая (состоящая исключительно из обязательных частей) программа:

class Program
{
static void Main()
{
}
}

🔶 Довольно интересным типом программ, на мой взгляд, являются Куайны (Quine), названные так в честь американского логика и философа Willard Van Orman Quine (1908—2000).

Куайн (квайн, англ. quine) — компьютерная программа, которая выдаёт на выходе точную копию своего исходного текста.

Заинтригованы? Тогда попробуйте написать куайн на C# самостоятельно 😉

p.s. Один из многочисленных вариантов вы сможете найти по ссылке.

@csharp_1001_notes
#basics

Консольное приложение и класс Console

Консольный тип проектов один из самых простых и, вероятно, наиболее используемый при разработке на языке C#. Одним из определений консоли считают программное обеспечение, реализующее текстовый интерфейс.

Ниже я приведу основные методы класса Console (сигнатуры опущены намеренно ввиду наличия у некоторых из них перегрузок):

🔶 Console.Read - считать символ

🔶 Console.ReadLine - считать последовательность символов

🔶 Console.Write - отобразить значение

🔶 Console.WriteLine - отобразить значение и перевести каретку в начало ('\r') следующей строки ('\n')

Простенький пример их использования так же доступен по ссылке.

А вот и пример чуть посложнее, где автор использовал консольное приложение для небольшого "опроса" с начислением очков за правильные ответы.

💬 Почаще разбирайте код других разработчиков, чтобы набивать руку в чтении и подсматривать интересные для себя моменты, ведь программирование- это не только написание кода, но и его чтение ☝️

@csharp_1001_notes
#basics

Как и зачем возвращать результат выполнения метода Main

По умолчанию точка входа в наше приложение - метод Main объявлен с типом возвращаемого значения void. Однако, мы так же имеем возможность возвращать и целочисленное значение int (а начиная с C# 7.1 ещё и Task<int>):

class Program
{
static int Main()
{
if (DateTime.Today.DayOfWeek == DayOfWeek.Monday)
return -1; // Monday is bad
else
return 0;
}
}

Нужно это в первую очередь для того, чтобы код, вызывающий нашу программу, имел возможность отреагировать на результат её выполнения.

Стоит заметить, что сделать это получится лишь в том случае, когда информация о возвращаемых значениях и способах реагирования на них будет определена заранее, как в следующем примере на powershell:

dotnet run
if ($LastExitCode -eq 0) {
Write-Host "Execution succeeded"
} else
{
Write-Host "Execution Failed"
}
Write-Host "Return value = " $LastExitCode

💬 А знаете ли вы, что alias void в языке C# соответствует структуре public struct Void из сборки System? 😉

@csharp_1001_notes
Может ли Main быть public?

TL;DR
Может, но Microsoft не рекомендует:

Main must be static and it need not be public.

🔶 Почему может? Потому что язык C# и платформа .NET не накладывают никаких ограничений на модификаторы доступа для метода Main и следующий код будет успешно скомпилирован:

class Program
{
static public void Main()
{
Console.WriteLine("This would compile..");
}
}

🔶 Почему не рекомендуется? Потому что предполагается, что данный метод будет вызван лишь 1 раз исполняющей средой (CLR) и является точкой входа в ваше приложение.

В случае же наличия у него модификатора доступа public, он станет доступен для вызова из других частей вашего приложения.

💬 Тем, кто так же как и я озадачился закономерным вопросом "А как на самом деле вызывается метод Main и что происходит до него?" я прикладываю эту ссылку на строку в CoreCLR, ответственную за его вызов 😉

#basics
❇️ Минула очередная неделя, а значит время небольшой подборки на выходные.

Предлагаю вашему внимаю самые 🔥 интересные материалы этой недели:

🔸 Топ-10 докладов DotNext 2018 Piter

🔸 Время занимательных историй: исключительно исключительные ситуации

🔸 Обзор задач по алгоритмам — генерация множеств

🔸 Как дела с производительностью в асинхронном программирование на C#?

🔸 C# Back to Basics – Access Modifiers in C#

🔸 Lazy<T> why does it get Func<T>

Всем хороших выходных 😉

#sof_weekly
Что такое CIL (ранее MSIL) код и как его увидеть?

Common Intermediate Language (сокращённо CIL) — «высокоуровневый ассемблер» виртуальной машины .NET,- промежуточный язык, разработанный компанией Microsoft для платформы .NET Framework.

Все компиляторы, поддерживающие платформу .NET, транслируют код с языков высокого уровня на язык CIL (в среде разработки Visual Studio это C#, Managed C++, Visual Basic .NET).

Далее CIL код компилируется в native code с помощью JIT (just-in-time) компилятора, который и исполняется в CLR.

Так каким же образом можно увидеть CIL код?

В большинстве случаев для этого используется IL Disassembler (ildasm.exe), найти который можно по следующему пути:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64

ildasm.exe позволяет увидеть:

🔶 Список всех классов и методов в вашей сборке (assembly)

🔶 Содержимое manifest сборки

🔶 IL code всех методов, реализованных в сборке

На деле это выглядит следующим образом.

Подробнее про CIL код и процесс исполнения можно почитать на MSDN - Managed Execution Process.

Понравилась заметка? Тогда поделись ей с другими 😉

#assemblies
В чём причина существования CIL?

Закономерный вопрос.

Почему бы сразу не компилировать C# код в native code имея для этого лишь один компилятор? Для чего необходимо было создавать ещё один промежуточный язык-посредник и компилятор для него?

Как писал Eric Lippert,- два компилятора с промежуточным языком, как это не парадоксально, являются менее дорогим решением в случае с платформой .NET и чтобы это понять, следует вглянуть на ситуацию чуть шире.

🔶 Предположим, у нас есть n языков программирования (далее ЯП): C#, VB, F#, JScript и другие.

🔶 Предположим, у нас так же есть m различных сред выполнения (runtime environment): Windows на базе x86 и x64, XBOX 360, мобильные и другие.

🔶 Предположим, мы хотим придерживаться изначальной стратегии с компиляцией ЯП непосредственно в native code среды выполнения.

Сколько в таком случае нам потребуется компиляторов, чтобы каждый ЯП (n) мог скомпилироваться под каждый runtime (m)?

Ответ: n x m.

Так а что же с CIL? В случае наличия промежуточного языка, нам потребуется n компиляторов из ЯП в CIL и m компиляторов из CIL в runtime.

Как результат, кол-во компиляторов составит всего лишь n + m (что значительно меньше, учитывая кол-во ЯП и доступных runtime в случае с .NET).

Так же стоит учесть тот факт, что те, кто разрабатывают ЯП совершенно не обязательно знают все нюансы каждой платформы, в которой ЯП в дальнейшем будет исполняться.

Более того, если мы хотим иметь возможность исполнять все существующие ЯП для каждого нового runtime, то всё что нам необходимо будет сделать, так это написать единственный JIT компилятор из CIL в native code этого runtime 😉

💬 Если верить wikipedia, то на сегодняшний день компиляцию в CIL поддерживают более 30 языков программирования ☝️

#assemblies
Как получить аргументы командной строки?

Если ваше приложение запускается из командной строки, то ему можно передать один или несколько аргументов. Для того, чтобы получить их внутри самого приложения, достаточно объявить сигнатуру метода Main следующим образом:

 void Main(string[] args)


В этом случае аргументы могут быть получены непосредственно из входного аргумента args следующим образом:

 void Main(string[] args)
{
// List all arguments
foreach (string arg in args) {
Console.Write(string.Format("Arg: {0}", arg));
}

// Use 1st argument as filename
if (args.Length > 0) {
string name = args[0];
Console.Write(string.Format("File={0}", name));
}
}


💬 Стоит заметить, что максимальная длина командной строки на компьютерах под управлением Microsoft Windows XP или более поздених версий не может превышать 8191 символ. В случае превышения придётся использовать файлы 🙂

#basic