На основе примера из статьи набросал минимальный рабочий пример на C# 8.0 (можно и на предыдущей версии, если убрать null-coalescing assignment оператор ??=, который я использовал чтобы уместить тело метода в одну строку). Ещё неплохо было бы сделать очистку обработчиков при выходе из области и перегрузку обработчиков в дочерних областях, но мне лень.
Код
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using static ConsoleApp1.Effects;
namespace ConsoleApp1
{
class Program
{
delegate Task<IEnumerable<FileSystemInfo>> OpenDirectory(DirectoryInfo dir);
delegate void Log(string message);
delegate void HandleFile(FileInfo file);
static async Task Main(string[] args)
{
Handle<Log>(Console.WriteLine);
Handle<OpenDirectory>(async dir =>
{
await Task.Delay(100);
return dir.GetFileSystemInfos();
});
var files = new List<FileInfo>();
Handle<HandleFile>(files.Add);
await EnumerateFiles(new DirectoryInfo(@"D:\"));
}
public static async Task EnumerateFiles(DirectoryInfo dir)
{
var contents = await Perform<OpenDirectory>()(dir);
Perform<Log>()($"Enumerating files in '{dir}'");
foreach (var file in contents.OfType<FileInfo>())
{
Perform<HandleFile>()(file);
}
Perform<Log>()($"Enumerating subdirectories in '{dir}'");
foreach (var directory in contents.OfType<DirectoryInfo>())
{
await EnumerateFiles(directory);
}
Perform<Log>()("Done");
}
}
public class Effects
{
private static readonly AsyncLocal<Dictionary<Type, object>> Handlers = new AsyncLocal<Dictionary<Type, object>>();
[DebuggerStepThrough]
public static void Handle<T>(T handler) where T : Delegate
=> (Handlers.Value ??= new Dictionary<Type, object>())[typeof(T)] = handler;
[DebuggerStepThrough]
public static T Perform<T>() where T : Delegate
=> (T)Handlers.Value?[typeof(T)];
}
}
Для повышения детализации можно использовать систему с двумя камерами. Первая камера, в нашем случае, это тепловизионная матрица, которая даёт информацию о цвете, а вторая — ч/б камера с более высоким разрешением, которая даёт детализацию. Подобная схема, например, используется в некоторых флагманах Huawei.
Есть многообещающий проект Avalonia, который ещё пока находится в разработке. Кросплатформенный, даже на мобильных устройствах. Очень похож на WPF, но с некоторыми улучшениями. Можно использовать псевдоклассы, как в CSS и указывать размеры колонок и строк в гриде вот так ColumnDefinitions=«24,Auto,24». Может через год-два дойдут до версии 1.0.
Как же много людей не знает про бюджетное правило, да и про миллион других вещей в экономике и политике.
На основе примера из статьи набросал минимальный рабочий пример на C# 8.0 (можно и на предыдущей версии, если убрать null-coalescing assignment оператор
??=
, который я использовал чтобы уместить тело метода в одну строку). Ещё неплохо было бы сделать очистку обработчиков при выходе из области и перегрузку обработчиков в дочерних областях, но мне лень.