C# (C Sharp) programming
По всем вопросам- @notxxx1 Реестр РКН: https://clck.ru/3Fk3kb #VRHSZ
Больше📈 Аналитический обзор Telegram-канала C# (C Sharp) programming
Канал C# (C Sharp) programming (@csharp_ci) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 18 126 подписчиков, занимая 7 044 место в категории Технологии и приложения и 36 287 место в регионе Россия.
📊 Показатели аудитории и динамика
С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 18 126 подписчиков.
Согласно последним данным от 30 августа, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -65, а за последние 24 часа — 0, при этом общий охват остаётся высоким.
- Статус верификации: Не верифицирован
- Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 15.36%. В первые 24 часа после публикации контент обычно набирает 7.44% реакций от общего числа подписчиков.
- Охват публикаций: В среднем каждый пост получает 2 784 просмотров. В течение первых суток публикация набирает 1 349 просмотров.
- Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 0.
- Тематические интересы: Контент сосредоточен на ключевых темах, таких как .net, api, логика, архитектура, string.
📝 Описание и контентная политика
Автор описывает ресурс как площадку для выражения субъективного мнения:
“По всем вопросам- @notxxx1
Реестр РКН: https://clck.ru/3Fk3kb
#VRHSZ”
Благодаря высокой частоте обновлений (последние данные получены 31 августа, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var funcs = new List<Func<int>>();
// Первая группа лямбд
for (int i = 0; i < 4; i++)
{
funcs.Add(() => i * i);
}
Console.Write("Squares: ");
foreach (var f in funcs)
Console.Write(f() + " ");
Console.WriteLine();
// Вторая группа лямбд с копией переменной
funcs.Clear();
for (int i = 0; i < 4; i++)
{
int j = i;
funcs.Add(() => j * j);
}
Console.Write("SquaresWithCopy: ");
foreach (var f in funcs)
Console.Write(f() + " ");
}
}
Ответ:
Squares: 16 16 16 16
SquaresWithCopy: 0 1 4 9
Объяснение
Первая группа лямбд
Лямбды захватывают переменную i по ссылке. К моменту, когда мы их вызываем в foreach, цикл уже завершился, поэтому i == 4. Каждая лямбда вычисляет 4 * 4 → 16.
Вторая группа лямбд
Внутри цикла для каждого значения i создаётся новая локальная переменная j, и лямбда захватывает именно её. При первой итерации j = 0, при второй j = 1 и т. д. Поэтому j * j даёт 0, 1, 4, 9 соответственно.
Такой приём (захват локальной копии переменной) позволяет избежать «одинообразного» результата и сохранить значение каждой итерации.
using System;
class Program {
static void Main() {
int a = 1000;
int b = 1000;
object x = a;
object y = b;
Console.WriteLine(x == y); // #1
Console.WriteLine(x.Equals(y)); // #2
}
}
🔢 Варианты ответа:
A)
True
B)
False
C)
True
D)
False
✅ Правильный ответ: C
💡 Почему?
- x и y — boxed значения типа int, то есть ссылки на два разных объекта в куче.
- x == y сравнивает ссылки, а не значения → False.
- x.Equals(y) вызывает метод Equals для int, который сравнивает значения → True.
📌 Подвох — в различии == и .Equals() при использовании упакованных типов.
@csharp_ci
public static IEnumerable<int> GetSlowData()
{
Console.WriteLine("Fetching data...");
yield return 1;
Thread.Sleep(1000);
yield return 2;
Thread.Sleep(1000);
yield return 3;
}
Теперь тебе нужно реализовать метод ProcessData(), который:
Вызывает GetSlowData() один раз.
Проходит по данным дважды: сначала фильтрует только чётные, потом считает сумму всех.
Не должен повторно "запрашивать" данные (то есть Fetching data... должен выводиться один раз).
Не должен использовать ToList(), ToArray() или другие методы, загружающие всё в память явно.
🧠 Вопрос с подвохом: Как реализовать ProcessData()?
Напиши реализацию:
public static void ProcessData()
{
// твой код здесь
}
🔎 Подсказка
Если ты просто используешь IEnumerable<int> и дважды к нему обращаешься — будет два запроса. Но есть один способ реализовать ленивое кэширование, не загружая всё в память сразу и не повторяя yield return.
Решение:
Если ты просто напишешь вот так:
```csharp
var data = GetSlowData();
var evens = data.Where(x => x % 2 == 0);
var sum = data.Sum();```
то GetSlowData() будет вызван дважды, потому что IEnumerable ленивый — и при каждом новом foreach начинается всё заново. Это видно по двойному выводу Fetching data....
🧠 Цель: пройтись по данным один раз, кэшируя элементы "на лету", и позволить другим перечислениям работать без повторного получения.
✅ Решение: Используем ленивый кеш — с помощью кастомного итератора
```csharp
public static void ProcessData()
{
var cached = new MemoizedEnumerable<int>(GetSlowData());
var evens = cached.Where(x => x % 2 == 0);
var sum = cached.Sum();
Console.WriteLine("Even numbers: " + string.Join(", ", evens));
Console.WriteLine("Sum: " + sum);
}```
А вот реализация ленивого кеширующего MemoizedEnumerable<T>:
```csharp
public class MemoizedEnumerable<T> : IEnumerable<T>
{
private readonly IEnumerator<T> _source;
private readonly List<T> _cache = new();
private bool _sourceFinished = false;
public MemoizedEnumerable(IEnumerable<T> source)
{
_source = source.GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
int index = 0;
while (true)
{
if (index < _cache.Count)
{
yield return _cache[index];
}
else
{
if (_sourceFinished || !_source.MoveNext())
{
_sourceFinished = true;
yield break;
}
_cache.Add(_source.Current);
yield return _source.Current;
}
index++;
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}```
🧪 Что происходит
MemoizedEnumerable запоминает каждый элемент один раз при первом проходе.
Следующие проходы используют кэш.
Fetching data... будет вызван только один раз.
💥 Подвох
Большинство подумает, что IEnumerable можно безопасно переиспользовать без сайд-эффектов. Но не тут-то было: без кэширования yield выполнится дважды. Многие Middle+ разработчики ошибаются именно тут.tsqlanalyze -i "C:\scripts\proc.sql" --format
Эта команда проанализирует и отформатирует указанный SQL-скрипт согласно установленным правилам.
📌 Подробнее о новых возможностях и инструкциях по установке читайте в официальной документации.
#sqlserver #tsql #dotnet #cli #devtools
https://github.com/ErikEJ/SqlServer.Rules/tree/master/tools/SqlAnalyzerCli#sql-formatting-preview
@csharp_ci
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var actions = new List<Action>();
for (int i = 0; i < 3; i++)
{
actions.Add(() => Console.WriteLine(i));
}
foreach (var action in actions)
action();
}
}
Варианты ответа:
A)
1
2
B)
3
3
C)
0
0
D)Ошибка компиляции
---
✅ Правильный ответ: B
Почему:
Лямбда-функции захватывают переменную i по ссылке, а не её значение на каждой итерации. После завершения цикла i == 3, и все замыкания ссылаются на одно и то же i. Это классическая ловушка замыканий в C#.
@csharp_ci