C# 1001 notes
Відкрити в Telegram
Регулярные короткие заметки по C# и .NET. Просто о сложном для каждого. admin - @haarrp
Показати більше6 680
Підписники
-424 години
-107 днів
+2230 днів
Архів дописів
6 680
#challenge
💻 Letter Distance | #easy
Given two words, the letter distance is calculated by taking the absolute value of the difference in character codes and summing up the difference.
If one word is longer than another, add the difference in lengths towards the score.
To illustrate:
"fly") = dist("h", "f") + dist("o", "l") + dist("u", "y") + dist(house.Length, fly.Length)
= |104 - 102| + |111 - 108| + |117 - 121| + |5 - 3|
= 2 + 3 + 4 + 2
= 11
Examples:
LetterDistance("sharp", "sharq") ➞ 1
LetterDistance("abcde", "Abcde") ➞ 32
LetterDistance("abcde", "bcdef") ➞ 5
🏆 Leave your solutions in the comments. The solution will be posted below in a couple of hours 👇
#interview6 680
📝 How can we check equality in .NET?
🔸 The
ReferenceEquals() method - checks if two reference type variables(classes, not structs) are referred to the same memory address.
🔸 The virtual Equals() method. (System.Object) - checks if two objects are equivalent.
🔸 The static Equals() method - is used to handle problems when there is a null value in the check.
🔸 The Equals method from IEquatable interface.
🔸 The comparison operator == - usually means the same as ReferenceEquals, it checks if two variables point to the same memory address. The gotcha is that this operator can be override to perform other types of checks. In strings, for instance, it checks if two different instances are equivalent.
#post6 680
📝 What is namespace in C#?
A namespace is designed for providing a way to keep one set of names separate from another. The class names declared in one namespace does not conflict with the same class names declared in another.
🔸 NET uses namespaces to organize its many classes.
🔸 Declaring your own namespaces can help you control the scope of class and method names in larger programming projects.
SampleNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside SampleNamespace");
}
}
}
#post6 680
#challenge
💻 Compounding Letters | #easy
Create a function that takes a string and returns a new string with each new character accumulating by +1. Separate each set with a dash.
Capitalize the first letter of each set.
Examples:
Accum("abcd") ➞ "A-Bb-Ccc-Dddd"
Accum("RqaEzty") ➞ "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy"
Accum("cwAt") ➞ "C-Ww-Aaa-Tttt"
🏆 Leave your solutions in the comments. The solution will be posted below in a couple of hours 👇
#interview6 680
📝 How to implement the Where method in C#?
The
yield keyword actually does quite a lot here. It creates a state machine "under the covers" that remembers where you were on each additional cycle of the function and picks up from there.
The function returns an object that implements the IEnumerable<T> interface. If a calling function starts foreaching over this object, the function is called again until it "yields" result based on some predicate.
This is syntactic sugar introduced in C# 2.0. In earlier versions you had to create your own IEnumerable and IEnumerator objects to do stuff like this.
#post6 680
📝 What is an Abstract Class?
The
abstract modifier indicates that the thing being modified has a missing or incomplete implementation. The abstract modifier can be used with classes, methods, properties, indexers, and events.
An Abstract class is a class which is denoted by abstract keyword and can be used only as a Base class.
Abstract classes have the following features:
🔸 An abstract class cannot be instantiated.
🔸 An abstract class may contain abstract methods and accessors.
🔸 It is not possible to modify an abstract class with the sealed modifier because the two modifiers have opposite meanings. The sealed modifier prevents a class from being inherited and the abstract modifier requires a class to be inherited.
🔸 A non-abstract class derived from an abstract class must include actual implementations of all inherited abstract methods and accessors.
#post6 680
Вебинар для разработчиков С++, которые хотят использовать последние возможности языка, а также для программистов на других языках, чтобы узнать, какие преимущества даёт разработка на C++.
Максимально кратко и содержательно расскажем о новых фичах Стандарта:
1. зачем они нужны и насколько они круты;
2. когда и для чего их можно будет использовать в своих программах;
3. особое внимание уделим модулям, концептам, диапазонам (Ranges), корутинам и трёхстороннему сравнению;
4. также поговорим и об остальных нововведениях.
25 февраля в 19.30 (Мск)
70 минут обзор + 20 минут ответы на вопросы
👉Бесплатная регистрация на сайте
6 680
Конкатена́ция строк в C#
В C# мы можем использовать оператор
+ не только для сложения чисел, но и склеивания (конкатенации) строк:
string s1 = "C#"; string s2 = "fun"; string s3 = s1 + " is " + s2; // "C# is fun"Мы можем использовать этот оператор неограниченное количество раз в рамках одного выражения (expression), а само выражение использовать в тех местах кода, где ожидается строка:
string s1 = "Hello " + " Wor" + "ld";
Console.WriteLine("Wish " + "you " + "the best");
Более того, специальные методы String.Concat и String.Format содержат дополнительные перегрузки, которые также могут быть использованы для конкатенации:
// Concat method
string s4 = String.Concat(new object[] {
"The ", 3, " musketeers"
});
string s5 = String.Concat("This", "That");
// Use String.Format to concatenate
string s6 = string.Format("{0}{1}{2}", s1, " is ", s2);
💬 Продолжая рассказывать про полезные фичи в C# нельзя не упомянуть coalesce оператор ??. Принцип его работы прост- возвращать left-hand операнд если он не null и right-hand в обратном случае: int y = x ?? -1. Берите на вооружение 😉
#strings6 680
❇️ Рабочая неделя заканчивается, а значит пришло время очередной недельной подборки на выходные.
Предлагаю вашему внимаю самые 🔥 интересные статьи и вопросы этой недели:
🔸 Why does Enumerable.Single() iterate all elements, even when more than one item has already been found?
🔸 How to use Factory Method Design Pattern in C#
🔸 C# Intermediate – Delegates in C#
🔸 How to properly implement an interface that was designed for async usage?
🔸 Secure Random Integers in .NET Core 3
🔸 .NET Standard vs. .NET Core
Всем отличных выходных 😉
#sof_weekly
6 680
Parse чисел в C#
Каждый числовый тип в C# содержит метод
Parse, с помощью которого мы можем преобразовывать строки в соответствующие числовые значения:
byte b1 = byte.Parse("200");
sbyte sb1 = sbyte.Parse("-100");
float f1 = float.Parse("1.2e-4");
Однако, важно отметить, что результат выполнения этого метода может обернуться для нас и следующими исключениями:
🔸 FormatException:
int n1 = int.Parse("3.4"); // FormatException
В этом примере мы пробуем привести (распарсить) дробное значение к типу int, в результате чего получаем исключение о некорректности формата входного параметра 3.4.
🔸 OverflowException:
uint ui1 = uint.Parse("-1"); // OverflowException
В данном случае мы пытаемся привести отрицательное число к типу uint, значения которого могут быть только положительными. Как итог - исключение, сигнализирующее о переполнении.
💬 Одним из полезных атрибутов, помогающем как в документации, так и в контроле поведения, является ObsoleteAttribute. С его помощью мы можем помечать элементы программы, которые больше не должны использоваться и вскоре могут быть удалены. Обычно мы получаем предупреждение, однако, знали ли вы, что это поведение настраиваемое и мы можем даже возвращать полноценную ошибку компиляции 🙂?
#strings6 680
Выключение контроля переполнения в C#
В предыдущей заметке я рассказывал о ключевом слове
checked и возможности устанавливать поведение по умолчанию в случае переполнения в рамках проектов. Нелишним будет упомянуть и о ключевом слове unchecked, которое делает обратное.
В том случае, если в настройках проекта в качестве поведения по умолчанию мы выбираем опцию выбрасывать исключения в случае переполнения, то unchecked может нам помочь избежать этого при необходимости:
int n1 = int.MaxValue; // 2147483647 (0x7FFFFFFF) int n2 = unchecked(n1 + 1); // Перенос -2147483648 int n3 = n1 + 1; // OverflowExceptionКак и в случае с
checked мы так же может использовать unchecked не только для конкретных операторов, но и целых участков кода:
int n1 = int.MaxValue; // 2147483647
unchecked
{
int n2 = n1 + 1; // Перенос -2147483648
int n4 = n1 * 2; // -2
}
Уверен, вы замечали, что следующий код не будет скомпилирован и отобразится ошибка:
int n1 = int.MaxValue + 1; // Ошибка компиляции: overflowВ этом случае нам также может помочь
unchecked:
int n2 = unchecked(int.MaxValue + 1);💬 Одной из полезных возможностей в Visual Studio для повышения продуктивности для меня являются сниппеты (настоятельно рекомендую ознакомиться всем тем, кто их не использует 😉). А какой из них вы используете чаще всего? #data_types
6 680
Контроль переполнения в C#
В прошлой заметке я уже упоминал о том, что по умолчанию при переполнении ведущие биты обнуляются, после чего результат "умещается" в доступных битах:
int n1 = int.MaxValue; n1 = n1 + 1; // -2147483648 (перенос)Однако это поведение может быть изменено и для этого мы можем воспользоваться ключевым словом
checked:
int n1 = int.MaxValue; n1 = checked(n1 + 1); // OverflowExceptionВ таком случае вместо продолжения выполнения программы будет выброшено исключение
OverflowException, которое мы можем или корректно обработать, или проигнорировать для завершения программы.
Синтаксис ключевого слова checked позволяет контролировать переполнение не только у конкретных операторов, но и целых блоков кода:
checked
{
int n1 = int.MaxValue;
n1 = n1 + 1; // OverflowException
}
Также стоит упомянуть о возможности изменения поведения при переполнении в настройках проекта: Project > Properties > Build > Advanced > Check for arithmetic overflow/underflow.
#data_types6 680
Переполнение в C#
Во время выполнения арифметических операций с целочисленными типами возможна ситуация, при которой итоговый результат выходит за рамки доступных значений результирующего типа (другими словами не может быть корректно представлен и размещён в памяти).
Такая ситуация называется переполнением (overflow) и корнями уходит к арифметике и битовому представлению чисел в computer science.
По умолчанию в C# и .NET при переполнении ведущие биты обнуляются, после чего результат "умещается" в доступных битах. В случае с беззнаковыми типами - большие значения станут меньше, а при переполнении знаковых типов положительные числа станут отрицательными.
Позвольте мне продемонстрировать это поведение на примерах:
🔸 Максимальным значением для беззнакового типа
uint является 0xffffffff:
uint u1 = 0xffffffff; u1 = u1 + 5; // 0x00000004 (перенос)🔸
int.MaxValue - максимальное значение для знакового типа int:
int n1 = int.MaxValue; n1 = n1 + 1; // -2147483648 (перенос)🔸 Минимальное значение для знакового типа
short является -32768:
short s1 = short.MinValue; s1 = (short)(s1 - 1); // 32767 (перенос)💬 Как я уже упоминал ранее, использовать минимальные и максимальные значения в циклах стоит с осторожностью, иначе это может привести к неожиданным последствиям. Примером тому служит следующий код. Что выведется на экране? Ответ вы сможете найти ниже на странице 😉 #data_types
6 680
❇️ Выходные на пороге, а значит время очередного еженедельного дайджеста.
Предлагаю вашему внимаю самые 🔥 интересные вопросы этой недели:
🔸 C# Intermediate – Queue, Stack, And Hashtable in C#
🔸 What does .NET's Equals method really mean?
🔸 Use structures to improve the readability of your code
🔸 Playing with C# 7 - Deconstruct
🔸 The Evolution of C#
🔸 IEnumerable<T> and .Where Linq method behaviour?
🔸 How to find all classes that implements a generic abstract class using reflection in C#?
🔸 Why are 1000 threads faster than a few?
Всем отличных выходных 😉
#sof_weekly
6 680
Округление чисел с плавающей точкой в C#
Во время разработки мы временами сталкиваемся с необходимостью округлить число с плавающей точкой типа
float или double к целочисленному значению типа int. Сделать это неявно, как я уже упоминал ранее, у нас не получится ввиду отсутствия реализации подобного приведения:
int n1 = 4.8f; // Cannot implicitly convertПоэтому в дело вступает явное приведение:
int n1 = (int)4.8f;Однако, с этим кодом всё не так просто. Дело в том, что подобное округление на деле окажется ничем иным, как отбрасыванием дробной части у целочисленного значения. Если же мы хотим руководствоваться математическими правилами округления, то с этим нам поможет класс System.Convert:
float f1 = 4.8f; int n1 = Convert.ToInt32(4.8f); // 5Но и здесь всё не всегда так гладко 😅 Оказывается, в .NET алгоритм округления (banker's rounding) отличается от привычного нам в тех случаях, когда значения являются пограничными: 0.5, 3.5. В этих случаях округление осуществляется в пользу ближайшего чётного:
int n1 = Convert.ToInt32(8.5f); // 8 int n2 = Convert.ToInt32(9.5f); // 10💬 Заинтересованы алгоритмом и причиной подобного решения в .NET? Подробнее почитать об этом вы сможете уже самостоятельно здесь 😉 #basics
