• Как загнать в dictionary key как null?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Напиши обертку
    var dict = new Dictionary<MyNullableInt, string>();
    dict[null] = "hello, world!";
    
    Console.WriteLine(dict[null]); // Output: hello, world!
    
    
    struct MyNullableInt: IEquatable<MyNullableInt>, IEquatable<int?>
    {
        public int? Value { get; set; }
        public bool Equals(MyNullableInt other)
        {
            return other.Value == Value;
        }
    
        public bool Equals(int? other)
        {
            return other == Value;
        }
    
        public static implicit operator MyNullableInt(int? value)
        {
            return new MyNullableInt() {Value = value};
        }
    
        public static implicit operator int?(MyNullableInt value)
        {
            return value.Value;
        }
        
        public override bool Equals(object? obj)
        {
            if (obj is int value)
            {
                return value == Value;
            }
    
            if (obj is MyNullableInt mni)
            {
                return mni.Value == Value;
            }
    
            return false;
        }
    
        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }
    }
    Ответ написан
    3 комментария
  • Как правильно и удобно читать данные из БД?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Думаю, что надо раскрыть подробнее тему предыдущих ответов и комментариев.
    Проблемы со сложностью у вас, потому что вы не используете современые средства .NET и C#.
    В .NET исторически сложилось несколько слоев API для обеспечения параллельной работы, и использование функций обратного выдова - самый старый и самый громздкий из них. А самый удобный и современный - это Task Parallel Library (TPL): он, плюс конструкции языка C# async/await, позволяет писать такой асинхронно выполняющийся код так, будто он выполняется синхронно.
    Скорее всего (я просто не уточнял, потому пишу так) для SQLite есть асинхронный API и для использования с TPL, и API для синхронного использования, что ещё удобнее - и он должен быть не менее быстрым чем синхронная работа с файлами, потому что это встроенная БД.
    Но если вы по каким-то причинам будете работать с асинхронным API на функциях обратного вызова, то тут тоже есть способ упростить код: транслировать вызовы такого API для использования его со средствами TPL. Для этого используйте объект типа TaskCompletionSource (в вашем случае - обобщенный, специалиированный вашим типом результата: TaskCompletionSource<int>
    У этого объекта есть свойство Task, возвращающее задачу, состоянием котрой можно управлять с помощью методов этого объекта - SetResult и других, вызывая эти методы в функциях обратного вызова (AKA callback). Как это делать - см. пример по ссылке.
    А с Task, каким бы способом вы его не получили, вам будет работать значительно удобнее: если пометить метод, в котором вам надо работать с БД как async (в современном C# так можно пометить даже Program.Main), то в этом методе можно будет использовать для получения значения операцию await
    TaskCompletionSource<int> tcs1=new TaskCompletionSource();
    //... операции по по настройке tcs1 и запуску первого чтения из БД
    int numberFromBase1 = await tcs1.Task.ConfigureAwait(false);
    TaskCompletionSource<int> tcs2=new TaskCompletionSource();
    //... операции по по настройке tcs2 и запуску второго чтения из БД
    int numberFromBase2 = await tcs2.Task.ConfigureAwait(false);
    int summ =  numberFromBase1 + numberFromBase2;
    return summ;

    Вызов ConfigureAwait(false) здесь нужен для избежания блокировок в некоторых контекстах синхронизации (приложения Windows Forms, WPF и др.). Если же у вас программа выполняется вне специфического контекста синхронизации - консольное приложение, приложение ASP.NET Core и др., - то этот вызов не обязателен.
    Компилятор, увидев операцию await, преобразует метод нужным образом, так, чтобы он выполнялся асинхронно, передавая управление другим задачам во время ожидания (т.е. до выполнения функции обратного вызова) и возобнавлял выполнение по его завершении -и вам думать об этом и писать нужный для этого код будет не нужно.
    Такой метод вернет Task (возможно - ещё до завершения всех операций) и с его результатом можно что-то сделать: либо получить его опять чере await асинхронно, либо дождаться завершения асинхронных операций с получением результата через вызов метода Task<int&gt.GetAwaiter().GetResult() (есть другие варианты, но этот IMHO лучше всего в плане обработки исключений).
    Ответ написан
    Комментировать
  • Кто-нибудь делал слой bff внутри api, а не отдельным сервисом?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    У нас на проекте есть сервис - прослойка для БД. По факту - он возвращает все значения из БД. Нам этого не надо было.
    Мы организовали типа BFF на нем: каждый сервис создает ручку специально для себя и получает значения, которые нужны только для него.
    С одной стороны - больше поддерживать, но с другой стороны это решает множество проблем
    Ответ написан
    2 комментария