Обложка канала

C# 1001 notes. Страница 3

Регулярные короткие заметки по C# и .NET. Просто о сложном для каждого.

  • C# 1001 notes

    ❇️ Всех ещё раз с прошедшим днём программиста! А сегодня уже пятница, а значит время очередной еженедельной подборки по C# и .NET.

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

    🔸 What's Coming to C#?

    🔸 Keynote from the people who build .NET

    🔸 C# Back to Basics – Working With Files, File and Directory

    🔸 How to determine the size of var?

    Всем удачных выходных 😉

    #sof_weekly
  • C# 1001 notes

    Выражения, операторы и операнды в C#

    Ранее мы уже рассматривали литералы и типы данных. Сегодня предлагаю определить такие понятия как выражения, операторы и операнды.

    Чаще всего выражение состоит из оператора, операндов и присваивания результата выполнения и выглядит следующим образом:

    int result = 1 + 2;


    В данном примере "+" является оператором сложения, который применяется к двум операндам (1 и 2), результат выполнения которого присваивается оператором "=" переменной типа int.

    Разумеется, в качестве операндов могут выступать не только литералы, но и переменные, константы, результаты выполнения других операторов или методов и так далее.

    Говоря про оператор присваивания можно заметить, что он достаточно прост и принимает два операнда. Left hand операнд является переменной, которой будет присвоен right hand операнд.

    x = 10;
    // = - operator
    // x - left hand operand
    // 10 - right hand operand

    x = y + z;
    // = - operator
    // x - left hand operand
    // (y + z) - right hand operand
    // + - operator
    // y - left hand operand
    // z - right hand operand


    Операторы присваивания и сложения это далеко не все доступные операторы. На данный момент их количество в языке C# составляет уже более 42 штук.

    💯 Дорогие подписчики, сегодня, в 256 день в году, поздравляю всех вас с днём программиста 🍰 А наш канал, со своей первой важной отметкой в 100 читателей. Спасибо что вы с нами!

    #basics
  • C# 1001 notes

    Булевы (Boolean) литералы в C#

    Булевы литералы или, говоря проще, логические значения "Истина" (да) и "Ложь" (нет) представлены ключевыми словами true и false.

    В исходном коде чаще всего используется ключевое слово bool, являющееся на деле alias для структуры System.Boolean:

    bool isValid = true;
    bool hasErrors = false;


    Значением по умолчанию является false.

    💬 Задумывались ли вы, почему в языке C# тип System.Boolean занимает 1 байт? Ведь для кодирования значений 0 и 1 достаточно всего лишь одного бита.

    Если вам интересно, почему же так происходит, то по этой ссылке вы узнаете ответ 😉

    #basics
  • Реклама

  • C# 1001 notes

    Что такое литералы (Literals) ключевые слова C#

    Литерал - это способ представления значения в исходном коде. Чаще всего мы используем их при инициализации переменных и констант, передаче в качестве аргументов в вызовы методов, форматировании и проверке значений на равенство.

    🔸 Boolean - true / false;

    🔸 Integer - 12, 24L, 100UL, 0x7DC;

    🔸 Floating-point - 1.0, 2.2F, 6.02E23, 123.45m;

    🔸 Character - 'b', 'Y', '!', '\n', '\x04DA';

    🔸 String - "C#", "Look Ӛ", "Line 1\nLine 2";

    🔸 Null - null;

    Начиная с C# 7.0 в нашем распоряжении так же появился не только новый вид литерала:

    🔸 Binary - 0b00001111, 0b1111000011110000;

    Но и весьма удобный с точки зрения читаемости способ их записи посредством разделения с помощью _:

    ushort s1 = 0b1011_1100_1011_0011;
    int x1 = 0x44aa_abcd;


    Чуть более подробно можно почитать в этой замечательной статье.

    💬 А знаете ли вы, что кроме стандартного объявления индексатора:

    public string this[string key] {
    get { return internalDictionary[key]; }
    }

    // Usage: something["x"]


    Мы можем также использовать params:

    public string this[params string[] keys] {
    get { return internalDictionary[key]; }
    }

    // Usage: something["x", "y", "z"]


    Ни разу не пригодилось, но крайне любопытно 😉

    #basics
  • C# 1001 notes

    Контекстные (Contextual) ключевые слова C#

    Язык C# включает в себя перечень ключевых слов (keywords), использование которых определяется контекстом выполнения. Говоря проще, когда они находятся в нужном месте, они выполняют определённую для них функцию:

    var x = "y";
    dynamic m = "n";
    string t = nameof(x);


    В противном случае- они ничем не отличаются от обычных идентификаторов.

    Вот их неполный список: async, dynamic, global, join, value, await, select, var, get, nameof, set и другие.

    Более того, они не являются зарезервированными, а значит их можно (но так же не рекомендуется ⛔️) использовать в качестве имён без специального символа @ следующим образом:

    var var = "";
    bool async = false;
    string dynamic = "";
    int get = 1;


    Стоит заметить, что кроме contextual keywords так же в языке существуют следующие группы ключевых слов:

    🔸 Statement keywords;

    🔸 Operator keywords;

    🔸 Conversion keywords;

    🔸 Access keywords;

    🔸 Literal keywords;

    🔸 Query keywords;

    Количество ключевых слов продолжает рости по мере развития языка и на сегодняшний день оно составляет уже 78 штук.

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

    #basics
  • C# 1001 notes

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

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

    🔸 Джеффри Рихтер о том, как кодить, писать книги и создавать свои компании

    🔸 C# Back to Basics – Arrays in C#

    🔸 What function will be called?

    🔸 Enumeration in .NET V — ToList() or not ToList()?

    🔸 How to round to nearest even integer?

    Всем удачных выходных 😉

    #sof_weekly
  • C# 1001 notes

    Идентификаторы и правила их именования в C#

    Под идентификатором (identifier) в языке C# считаются любые имена, которые мы используем в именах переменных, классов, интерфейсов, методов, свойств, пространств имён и так далее.

    На именование идентификаторов накладываются следующие ограничения:

    🔸 Case sensitive - name != Name;

    🔸 Не могут начинаться с цифр;

    🔸 Не могут содержать пробелы;

    🔸 Могут включать в себя Unicode символы: string имя = ""; и class 国家 { } вполне себе валидные идентификаторы, но делать так без необходимости противопоказано ⛔️ То же относится и к именованию файлов в вашем проекте;

    🔸 Не могут совпадать с ключевыми словами (keywords) языка;

    Что касается последнего правила, то обойти его можно используя символ @ в качестве префикса в имени идентификатора, однако, без веских на то причин, я вам так же порекомендую этого не делать:

    class @class
    {
    int @int;
    string @default;
    }


    #basics
  • C# 1001 notes

    Какие методы поддерживают форматирование составных строк в C#?

    Ранее я уже упоминал, что одним из основных способов форматирования строк является использование метода string.Format, однако в платформе .NET он далеко не единственный.

    Сегодня я приведу расширенный список, поддерживающий данную функциональность:

    🔸 Console.Write / Console.WriteLine

    🔸 Debug.WriteLine

    🔸 StreamWriter.Write / StreamWriter.WriteLine

    🔸 StringBuilder.AppendFormat

    🔸 StringWriter.Write / StringWriter.WriteLine

    🔸 TextWriter.Write / TextWriter.WriteLine

    🔸 Trace.TraceError / Trace.TraceInformation

    Другими словами, следующая строка:

    string.Format("{0} is {1} yrs old.", name, age);


    Может быть переписана следующим образом:

    Console.Write("{0} is {1} yrs old.", name, age);


    Минутка занимательных наблюдений: Размер окна консольного приложения, оказывается, также может изменяться во время исполнения с помощью метода Console.SetWindowSize(w, h) 🙂

    #strings
  • C# 1001 notes

    Использование массива параметров при форматировании строки в C#?

    В том случае, когда список параметров для форматирования строки у нас достаточно длинный, или же он формируется динамически во время выполнения программы, мы можем воспользоваться одной из перегрузок метода string.Format, принимающей object[] args.

    Сделать это можно следующим образом:

    object[] args = { "London", 2017, 8825000 };
    string res = string.Format("{0}'s population in {1} is {2:0,0}.", args);


    Результат выполнения:

    London's population in 2017 is 8.825.000.


    Знали ли вы, что с помощью поля Console.Title вы можете изменять имя окна вашего консольного приложения и даже сделать его анимированным? 😀

    #strings
  • C# 1001 notes

    Форматирование и составные строки в C#?

    В процессе разработки мы довольно часто сталкиваемся с необходимостью использования комбинированных из разных частей строк.

    Чаще всего нам в этом помогает string.Format, принимающий шаблон строки и аргументы для подстановки.

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

    🔸 Подстановка

    Использования индексов в фигурных скобках для позиционирования аргумента в итоговой строке:

    string name = "C# channel";
    int age = 1;
    string res = string.Format("{0} is {1} yrs old.", name, age);

    // Output:
    // C# channel is 1 yrs old.


    🔸 Форматирование

    C2 как пример денежного формата:

    decimal value = 123.456m;
    Console.WriteLine("Your account balance is {0:C2}.", value);

    // Output:
    // Your account balance is $123.46.


    🔥 Выравнивание

    Указывая целочисленные значения после запятой мы можем задавать как отступы, так и выравнивание по левому/правому краям.

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");


    Результат выполнения.

    #strings
  • C# 1001 notes

    ❇️ Выходные на пороге, а значит время очередного еженедельного дайджеста.

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

    🔸 C# Back to Basics – Ref and Out Keywords in C#

    🔸 Непрерывный рост JSON

    🔸 Find duplicate in array with a memory efficient approach

    🔸 Принцип Дирихле́ для эффективного решения ☝️

    🔸 IDictionary How to get the removed item value while removing

    Всем отличных выходных 😉

    #sof_weekly
  • C# 1001 notes

    Как запускать приложение в Visual Studio с предопределёнными аргументами?

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

    Сегодня я хочу поделиться с вами одним из способов указать необходимые аргументы при разработке в Visual Studio по умолчанию.

    Это может быть особенно полезно как при отладке, так и в целях тестирования.

    Сделать это можно в свойствах проекта:

    Properties > Debug > Command line arguments.

    Вот как это выглядит.

    Так же стоит отметить, что:

    🔶 Данный способ подходит для всех типов проектов: консольных, Win Forms, WPF и т.д.

    🔶 Вы можете сами указать различный список аргументов для каждой из конфигураций (Debug или Release)

    ☝️ Однако, работает этот способ лишь в том случае, если приложение запускается непосредственно из среды разработки. Другими словами, в случае самостоятельного запуска .exe файла из каталога или командной строки указанные ранее аргументы передаваться не будут.

    #visual_studio
  • C# 1001 notes

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

    Если ваше приложение запускается из командной строки, то ему можно передать один или несколько аргументов. Для того, чтобы получить их внутри самого приложения, достаточно объявить сигнатуру метода 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
  • C# 1001 notes

    В чём причина существования 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
  • C# 1001 notes

    Что такое 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
  • Реклама

  • C# 1001 notes

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

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

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

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

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

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

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

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

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

    #sof_weekly
  • C# 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
  • C# 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