Ответы пользователя по тегу C#
  • Как по другому сделать?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Вынесите описания переменных наверх, над swicth.
    int PlayerDamage ;
    int PlayerHealth;
    int PlayerResist ;
    
     switch(characterChoose)
     {
         case 0:
             PlayerDamage = 50;
             PlayerHealth = 150;
             PlayerResist = 25;
             break;
         case 1:
             PlayerDamage = 75;
             PlayerHealth = 125;
             PlayerResist = 15;
             break;
    
     }

    PS Согласен с предыдущим комментатором - инциализация через оператор switch выглядит тяжеловесно. В нынешнем C# можно записать то же самое сильно короче, через деконструкцию, например.
    PPS Держите пример с вашеми данными, как это должно выгдядеть стильно-модно-молодежно:
    int characterChoose = Convert.ToInt32(Console.ReadLine());
    (int PlayerDamage, int PlayerHealth , int PlayerResist)=characterChoose switch
    {
        0 => (50, 150, 25),
        1 => (75, 125, 15),
       //... дописать все остальные варианты
    } ;
    Ответ написан
    Комментировать
  • Как применить настройки прокси-сервера через реестр в С#?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Браузеру надо сообщить, что настройки изменились парой вызовов процедуры InternetSetOption из WinInet.dll. Вызывать надо через P/Invoke На stackoverflow нашел пример, как это делать в Powershell.
    function Refresh-System
    {
      $signature = @'
    [DllImport("wininet.dll", SetLastError = true, CharSet=CharSet.Auto)]
    public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
    '@
    
    $INTERNET_OPTION_SETTINGS_CHANGED   = 39
    $INTERNET_OPTION_REFRESH            = 37
    $type = Add-Type -MemberDefinition $signature -Name wininet -Namespace pinvoke -PassThru
    $a = $type::InternetSetOption(0, $INTERNET_OPTION_SETTINGS_CHANGED, 0, 0)
    $b = $type::InternetSetOption(0, $INTERNET_OPTION_REFRESH, 0, 0)
    return $a -and $b
    }

    Адаптируйте этот код к C# (пояснение: Add-Type в PS служит для загрузки сборки или неуправляемой DLL ). Или поищите по имени этой процедуры код на C#.
    Ответ написан
    5 комментариев
  • Как десериализовать простой Json в массив?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Используйте LINQ:
    Если поле code в типе, получаемом после десериализации имеет тип int (по уму должно быть так, но я с NewtonSoft JSON не работал, поэтому не уверен в таких подробностях), просто допишите к выражению для десериализации
    .Select(x=>x.code).ToArray();
    Если тип, паче чаяния, другой - преобразуйте результат, возвращаемый лямбда-функцией в Select к int (для строки это будет Int32.Parse(x.code)
    Ответ написан
    Комментировать
  • Как правильно и удобно читать данные из БД?

    @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 лучше всего в плане обработки исключений).
    Ответ написан
    Комментировать
  • Нужно ли знать многопоточность и асинхронность в c#, чтобы начать учить asp.net?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Мое мнение: есть некоторая неопределенность для ответа. С одной стороны, при решении типовых задач с помощью базирующихся на ASP.NET Core фреймворках высокого уровня - MVC, Razor, Minimal API, Blazor (за последний не совсем уверен, правда), с асинхронностью и многопоточностью вы сталкиваться будете не сильно и не часто, потому что в них приложены усилия, чтобы изолировать разработчика от связанных с этим трудностей - короче, потребуется разве что, умение использовать async/await. Но в целом ASP.NET Core - это фреймворк асинхронный и многопоточный, поэтому для более плотной работы с ним понимание асинхронность и многопоточность и связанные с ней знания (например, про примитивы синхронизации, состояние гонок и т.п.) может быть полезно, иногда - например, если вы захотите использовать объекты, к которым возможен доступ из нескольких веб-запросов параллельно - просто необходимо.
    Короче, мое мнение: начинать изучать перечисленные фреймворки высокого уровня можно и без особых знаний про асинхронность, достаточно научиться использовать await в async-методах (это просто). Но в дальнейшем тему асинхронности и многопоточности надо вкурить, чтобы можно было работать смелее и свободнее, выходя за рамки фрейворка, и не допускать при этом труднообнаружимых ошибок.
    Ответ написан
    Комментировать
  • C#, обработка исключений, почему нельзя обратится к свойству, через имя класса?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    если я не хочу создавать переменную

    А вы её и так, и так не создаете: экземпляр исключения создается при возбуждении исключения (помните синтаксис - throw new Exception() )? А вот чтобы обратиться к полям/свойствам/методам этого экземпляра, надо дать ему имя в конструкции catch и обращаться к нему по этому имени. А при указании в качестве имени экземпляра имени класса, вы, как выше вам написал Василий Банников , как и в любом другом месте, обращаетесь к статическому полю (или свойству) этого класса. Такой вот синтаксис у языка C#: обработчик исключения у него - это обычный блок, никаких специальных соглашений там нет( пока что, по крайне мере ;-) ).
    Ответ написан
    2 комментария
  • Почему надо явно добавлять пакет Microsoft.NET.Test.Sdk в гл проект, если в одном из пакетов он уже есть?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Так нужно, потому что ссылки не транзитивны. Средства разработки не могут взять метаданные (описания сборок, классов и т.д.), которые нужны для работы и компилятора, и других средств разработки (IDE, в частности), из ссылок того проекта (по факту - тоже сборки), на который ссылается текущий. Так что для использования какой либо сборки (в данном случае - из состава пакета), ссылку на нее нужно добавлять в проект явно.
    Ответ написан
    2 комментария
  • Почему я не могу выбрать проект для дебага?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Если надо один раз: правой кнопкой мыши на нужный проект -> Debug -> Start New Instance
    Если надо изменить на постоянку: правой кнопкой мыши на нужный проект -> Configure Startup Project...
    или Меню->Project->Startup Project...
    Предполагается, что все эти проекты входят в одно Решение (Solution)
    Ответ написан
    Комментировать
  • Почему не работает замена буфера?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Так, как вы сделали, приложения для Windows GUI не пишутся. У вас цикл с ожиданием сделан совершенно неправильно.
    Обработка всего графического интерфейса в программе (в том числе и буфера обмена) в Windows выполняется одним потоком, через цикл сообщений. А вы этот поток захватили и не отдаете. Возможно, именно поэтому не работает и установка содержимого буфера обмена: ЕМНИП она тоже реализована через сообщения (но точно не помню), а шанс обработать очередь сообщний у вашей программы нет.
    Короче, переписывайте цикл чтобы никаких Thread.Sleep в нем не было. Например - добавляйте в форму таймер (System.Windows.Forms.Timer) и переносите вашу обработку буфера обмена в обработчик его события Tick.
    А там уже смотрите - работает она, или нет.
    Ответ написан
    Комментировать
  • C# SqlTransaction блочит таблицу, как обойти блокировку или что делаю не так?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Игрался с уровнями блокировок connection.BeginTransaction(IsolationLevel.....) ни к чему это не привело.

    Попробуйте обе транзации - и основную, и в мелком методе - делать с уровнем изоляции Snapshot.
    По умолчанию изоляция транзакций в MS SQL реализуется через блокировки (изначально - обрабатываемых записей, но может переползти и на всю таблицу).
    А вообще, при работе с незакрытй транзакциейоя бы передавал в мелкий метод то подключение, на котором открыта транзакция, чтобы он работал с ней. Можно сделать этот параметр необязательным (null по умолчанию) и в случае, если он не передан - открывать дополнительное подключение.
    Ответ написан
    2 комментария
  • Как правильно называть такую композицию классов?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    IMHO это - вариант шаблона "Абстрактная фабрика"
    Первая приходящая на ум альтернтатива - та, в которой этот шаблон используется традиционно: реализации наследуются от абстрактного класса фабрики (см. пример для C# в статье по ссылке), а не получаются аггрегированием фактичекой реализации со статическим классом, предостатвляющим интерфейс, как у вас.
    Ответ написан
    Комментировать
  • Как записать названия папок в массив?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Есть: применить к каждому возвращенному имени папки функцию (статический метод) Path.GetRelativePath и записать результаты в новый массив. Короче всего это записать через LINQ, примерно так:
    String[] rel_folder_names = Directory.GetDirectories(RootFolder).Select(s=>Path.GetRelativePath(RootFolder,s)).ToArray();

    Но если пока не умеете или боитесь использовать LINQ, то можно это сделать в обычном цикле
    String[] full_folder_names=Directory.GetDirectories(RootFolder);
    String[] rel_folder_names = new String[](full_folder_names.Length);
    for(int i=0;i<full_folder_names.Length;i++) {
         rel_folder_names[i]=Path.GetRelativePath(RootFolder,full_folder_names[i]);
    }

    Как-то так.

    PS Весь код написан "из головы", так что ошибки могут быть.
    Ответ написан
    4 комментария
  • Откуда stackoverflow при работе с stackalloc c#?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Похоже (явного указания в документации я не нашел), что память в стеке освобождается только при выходе из всего метода, но не из блока внутри него. Освобождение памяти в стеке, как известно - это сдвиг указателя стека обратно, и похоже, этого в конце блока не происходит - только в конце метода. Косвенное подтверждение - в документации по stackalloc явно написано избегать вызовов stackalloc в цикле, как это у вас сделано: "Avoid using stackalloc inside loops. Allocate the memory block outside a loop and reuse it inside the loop." ( https://learn.microsoft.com/en-us/dotnet/csharp/la... )
    Ответ написан
    Комментировать
  • ASP.NET Core 6 Как устранить ошибку при выполнении команды update-database?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    'MultipleActiveResults=True'

    Уберите эти одинарные кавычки.
    Ответ написан
    Комментировать
  • Реализовать ajax в asp dot net core 6?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Если вы умеете отправлять и получать запрос с фронта в формате JSON на голом JS через XMLHttpRequest или fetch (либо у вас есть фронтовой фреймворк для этого), то вам повезло: сама Microsoft о вас позаботилась. Как раз в ASP.NET 6 появился Minimal API. Суть его в том, что если раньше базовые делегаты-обработчики конечных точек маршрутизации (подключаемые через Map/MapGet/MapPost etc) должны были иметь тип RequestDelegate (HttpContext context на входе, Task на выходе, а в context.Response изволь писать сам), то теперь делегаты-обработчики могут иметь произвольный тип (ну, почти): принимать произвольное количество произвольных параметров - ASP.NET привяжет их к путям/параметрам в URL и содержимому тела запроса как надо - и возвращать произвольный объект в качестве результата - он будет правильно записан в context.Response: например, если это обычный объект, то он будет послан как JSON. То есть, Minimal API - это новый способ написания контроллеров API, безо всякого MVC.
    Что касается вашего вопроса: если вы передадите с фронта через XHR/fetch объект в JSON с полями и значениями в них, то ASP.NET привяжет параметры метода-обработчика к одноименным полям объекта, а объект, возвернутый из метода-обработчика, закодирует в JSON. И никакого дополнительного фреймворка не надо.
    Подключаются эти обработчики все теми же методами Map/MapGet/MapPost etc: просто в качестве делегата передаете не RequestDelegate а нужный метод-обработчик.
    Но есть нюанс: в документации по ASP.NET 6 все это великолепие еще толком не описано - читайте документацию по ASP.NET 7: она в целом подходит, только не испольуйте группы маршрутизации и фильтры - их в ASP.NET 6 ещё не было.
    PS Кому интересно: как это работает под капотом(конкретно для ASP.NET 7), описано в серии статей Эндрю Лока (знаете такого автора книжек по ASP.NET?).
    Ответ написан
  • Как адаптировать MapPost в метод ControllerBase?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Вынесено из комментариев (не туда запостил):

    Если бы я был контроллером API на MVC, я бы тоже так же ответил: "что за фигню вы мне прислали?" (в протоколе HTTP это обозначается кодом статуса 400).
    Контроллер API ждет, что вы ему пришлете, нечто, содержащее значение для параметра message вашего метода действия. Если вы посылаете в формате JSON, то - объект с полем message: тогда он привяжет значение этого поля входному параметру метода действия, который имеет то же имя message, как у вас.
    Потому в запросе POST надо слать объект с этим полем. Например - в уже сериализованном (строковом) формате:
    string content = "TestContent";
    Но можно в качестве content использовать и объект с полем message, например - анонимного типа:
    var content = new { message = "TestContent" };
    - PostAsJsonAsync сумеет превратить это в JSON.

    И да, к контроллеру на Minimal API из вашего первого комментария все это точно так же относится.
    Ответ написан
    Комментировать
  • У меня C# visual stiudio code в коде я пытаюсь отправить текст но появляется все равно hello, world что делать?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Меня смущает имя вашего класса: Programs. Посмотрите, нет ли у вас в проекте класса Program (без 's')? ;-)
    Ибо выполнение программы начинается с метода Main класса Program.
    Ответ написан
    Комментировать
  • Почему нельзя писать поле в интерфейсе?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Потому что интерфейс, по идее, не содержит внутри себя никаких данных - только список методов.
    Поэтому полей в интерфейсе нет. А свойства - это не поля, это упрощенный синитаксис для вызова методов-аксессоров: метода получения связанного с объектом значения и (если реализовано) его установки. Поэтому ничто не мешает интерфейсу их содержать.
    PS Автоматически реализуемое свойство объекта - типа того, что вы написали в начале - оно только внешне похоже на описание свойства в интерфейсе. В интерфейсе пустые тела аксессоров (так же, как и других методов) означают, что наследующий этот интерфейс класс обязан их реализовать. А автоматически реализуемое свойство объекта - это синтаксический сахар, скрывающий от глаз реализацию: автоматически создаваемое компилятором поле с простейшими аксессорами - прочитать поле и записать в поле.
    Ответ написан
    Комментировать
  • В чем различие между делегатоми и событиями?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Событие (event) - это синтаксический сахар, которым посыпан механизм вызова одного или несколких методов на основе базового для всех делегатов встроенного типа Delegate (вызов нескольких методов реализует класс MulticastDelegate, унаследованный от Delegate) Компилятор же, встретив ключевое слово event, создает переменную-делегат указанного типа с тем же именем (далее ИмяСобытия), доступную только внутри класса (т.е. private) и два метода: add_ИмяСобытия и remove_ИмяСобытия. А встретив операторы += и -= для подписки/отписки вызывает соответсвующий метод. Подробнее можно посмотреть в главе 11 книги Джеффри Рихтера "CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#".
    Вызывать несколько методов можно и через один делегат - см. пример в справке для класса MulticastDelegate.
    Ответ написан
    Комментировать