Ответы пользователя по тегу C#
  • Cannot convert return expression of type, C# generic method, как вернуть конкретный тип?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    как можно вернуть конкретный тип значения без изменения сигнатуры?

    В данном случае - никак.
    T - это generic параметр для подстановки во время компиляции. Он означает конкретный тип.
    Так как никаких ограничений на него не выставлено, то считается, что может в него быть вставлено абсолютно что-угодно. Но возвращаемые значения должны уметь конвертироваться в этот возвращаемый тип, например, если T - long, то ParseInt сработает, т.к. int конвертируется к long (неявно и явно), а DateTime к long просто так нет. А теперь вместо T подставь byte или какой-нибудь класс и подумай - можно ли int к этому классу сконвертировать.

    Пишу парсер

    Когда я писал свой парсер, то делал базовый класс с абстрактным свойством, которое показывает что это за тип, и для каждого возможного значения - отдельный класс, который наследуется от базового. Чтобы понимать, что в результате пришло - смотрю на это поле.

    Дополнительно, в данном случае лучше применять какую-нидудь фабрику этих парсеров, т.к. в рантайме через рефлексию определять свой тип и на основании него парсить - такое себе.

    Например, так можно

    enum TokenType
    {
        Int,
        Decimal,
        DateTime,
    }
    
    public abstract class ParseResult
    {
          public abstract TokenType Type { get; }
    }
    
    public class IntParseResult: ParseResult
    {
           public override TokenType Type => TokenType.Int;
           public int Value { get; }
           IntParseResult(int value)
           {
                 Value = value;
            }
    }
    
    public class DecimalParseResult: ParseResult
    {
           public override TokenType Type => TokenType.Decimal;
           public decimal Value { get; }
           DecimalParseResult(decimal value)
           {
                 Value = value;
            }
    }
    
    public class DateTimeParseResult: ParseResult
    {
           public override TokenType Type => TokenType.DateTime;
           public DateTime Value { get; }
           DateTimeParseResult(DateTime value)
           {
                 Value = value;
            }
    }
    
    public interface IParser
    {
              ParseResult Parse(string str);
    }
    
    public class IntParser: IParser
    {
            public ParseResult Parse(string str) => ParseInt(str);
    }
    
    public class DecimalParser: IParser
    {
            public ParseResult Parse(string str) => ParseDecimal(str);
    }
    
    public class DateTimeParser: IParser
    {
            public ParseResult Parse(string str) => ParseDateTime(str);
    }
    
    public static class MyParser
       {
           private static IParser GetParserFor(string str) { /* .... */ };
           public static ParseResult Parse(string str)
           {
                  var parser = GetParserFor(str);
                  return parser.Parse(str);
           }
       }


    Я рекомендую убрать этот статический парсер и вынести решение о том какой парсер использовать выше по иерархии вызовов, либо пересмотреть логику парсинга, т.к. просто посмотреть на строку и понять как парсить - не самое эффективное решение.
    Ответ написан
    Комментировать
  • WPF ошибка CS0103?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Класс помечен partial - проверь что оба объявления находятся в одном и том же неймспейсе что и в XAML разметке (тот что x:Class).
    Вот тут на SO похожая проблема - https://stackoverflow.com/questions/6925584/the-na...
    Ответ написан
  • Персонаж не прыгает в unity3D! Почему?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Вместо Input.GetButtonDown("Jump") используй Input.GetKeyDown(KeyCode.Space)
    Ответ написан
  • Какой шаблон проекта выбрать при написании телеграмм бота Visual Studio 2022?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Для простого телеграм бота подойдет и консольное.
    ASP.NET Core/Web.API - точно нет, т.к. они для веб-приложений, у тебя не такое.
    Также может подойти шаблон Worker Service, но он больше для каких-то сложных приложений.

    Предлагаю пока остановиться на консольном, но параллельно изучать Worker Service, т.к. в нем много удобных вещей - логирование, обработка исключений, мониторинг, DI и т.д.
    Возможно, однажды пригодится, но пока оставайся на консоли.
    Ответ написан
    2 комментария
  • Есть ли хороший курс/книга про использование паттерна page object на C#?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Курс/книга ради одного паттерна - вряд ли можно найти хорошие.
    Page Object паттерн из GUI тестирования, поэтому искать там. Рекомендую курс от Selenium - https://www.seleniumtraining.com/selenium-c-sharp-...
    Там как раз есть 6 часовой туториал с проектом по Page Object, но он в платной подписке.

    Также по тестированию на C# есть книга Selenium with C# - в 12 главе описывается Page Object

    Есть статья на хабре, но думаю она только описывает этот паттерн, только для знакомства
    Ответ написан
    1 комментарий
  • Фреймворки для кросс-платформенной разработки. Практикуют ли переписывание под разные платформы?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Windows Forms - это только Windows, т.к. он построен вокруг нативных системных вызовов Windows. Вообще-то я однажды писал Windows Forms для Linux, но там очень много было костылей и багов, поэтому - нет, не надо.

    Что касается кросс-платформенной разработки на C#.
    Если речь идет про разработку оконных приложений, то тут 2 варианта:
    - Avalonia UI - это кросс-платформенный фреймворк, разрабатываемый сообществом (не майкрософтом), очень похож на WPF. Есть почти все платформы
    - MAUI - это новый кросс-платформенный фреймворк, разрабатываемый майкрософтом. Он довольно новый, поддерживает множество платформ (по странице документации даже Linux (GTK#)). Но он довольно сырой и по отзывам очень много багов
    - WebAssembly/Blazor - фреймворк для создания PWA, веб-приложений, но можно и для мобильных приложений
    Ответ написан
    3 комментария
  • Как отследить то, что самопроизвольно закрывает приложения NET в Ununtu?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Автономные приложения под линуксом надо запускать как сервисы через systemd.
    Как это сделать можно почитать тут - https://habr.com/ru/companies/timeweb/articles/759966/

    С помощью этого, можно будет выставить политику повторного запуска при остановке, логи можно в syslog сохранять и подобное.
    Так как ты запускал это все в фоновом режиме и вышел, то родительским процессом стал init, все логи потерялись. Максимум можно дамп ядра получить, но это еще при выставленных настройках.

    Также я не услышал про логи (в каком они виде) - если есть лог файл, то смотри там, иначе ничего сказать не могу.

    Могу также порекомандовать запускать это все в докере. Немного замороченно, но та же самая функциональность (логи и рестарт), что и в systemd сервисе.
    Ответ написан
    1 комментарий
  • Объясните модификаторы доступа?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    В спецификаци C# ECMA-334 это описывается в терминах доменов доступности - Accessibility domain.
    Каждый модификатор доступа выставляет определенные ограничения на эту доступность. В результате, у тебя будут следующие "области" - A -> Method.
    Главное правило - ты не можешь получить доступ к member, которые не в твоем домене.
    Пример оттуда:
    Example: In the following code
    public class A
    {
     public static int X;
     internal static int Y;
     private static int Z;
    }
    internal class B
    {
     public static int X;
     internal static int Y;
     private static int Z;
     public class C
     {
     public static int X;
     internal static int Y;
     private static int Z;
     }
     private class D
     {
     public static int X;
     internal static int Y;
     private static int Z;
     }
    }

    the classes and members have the following accessibility domains:
    • The accessibility domain of A and A.X is unlimited.
    • The accessibility domain of A.Y, B, B.X, B.Y, B.C, B.C.X, and B.C.Y is the program text of the
    containing program.
    • The accessibility domain of A.Z is the program text of A.
    • The accessibility domain of B.Z and B.D is the program text of B, including the program text of
    B.C and B.D.
    • The accessibility domain of B.C.Z is the program text of B.C.
    • The accessibility domain of B.D.X and B.D.Y is the program text of B, including the program
    text of B.C and B.D.
    • The accessibility domain of B.D.Z is the program text of B.D. As the example illustrates, the
    accessibility domain of a member is never larger than that of a containing type. For example,
    even though all X members have public declared accessibility, all but A.X have accessibility
    domains that are constrained by a containing type.
    end example

    Для твоего примера - домены доступности для этих методов одни и те же (неявно возвращается глобальный System.Void), поэтому корректная конструкция.
    А вот если из публичного метода возвращать боле ограниченный тип, то будет нарушение. Т.к. возвращаешь более ограниченный из глобального.
    Ответ написан
    2 комментария
  • Как передать экземпляр объекта в другой класс?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Ты передаешь object, а не HttpClient

    class Class1 (HttpClient client)
        {
            public async Task StartVkAsync()
            {            
                using (HttpResponseMessage response = await client.GetAsync("https://ya.ru/"))
                {
                    var JsonString = await response.Content.ReadAsStringAsync();
                    await Console.Out.WriteLineAsync(JsonString);
                }
            }
        }
    Ответ написан
    1 комментарий
  • Какой метод надо использовать в Unity, что бы при нахождении в Trigger происходило событие?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Скорее всего, когда ты умираешь в области триггера, то выходишь из него. В этом случае, тебе нужен Collider.OnTriggerExit()
    Ответ написан
  • Нормально ли писать на C# на Linux Manjaro?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Устанавливай .NET Core и разрабатывай на здоровье.
    Разница с Windows разве что в отсутствии оконных приложений, а остальные типы проектов есть.

    P.S. Visual Studio придется забросить и перейти либо на VS Code либо на Rider
    Ответ написан
    Комментировать
  • Эффективный long polling запрос Telegram API каа правильно сделать?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Для чего нужен "timeout" в строке запроса?

    long polling - это когда делаешь запрос и ждешь пока произойдет окончание операции. в данном случае, окончание означает то, что какое-то событие произошло и получены обновления.
    И тут возникает вопрос - сколько ждать?
    Например, ты просто хочешь узнать есть ли новые сообщения - тут ждать не надо, ответ сразу, или это фоновый поток, который должен реагировать на каждое сообщение - тогда надо ждать пока не получишь сообщение, т.е. ждать можешь долго.
    Таймаут - это время, которое будет затрачено на эту операцию. Здесь оно выставляется в секундах.
    Если таймаут превышен, то соединение разрывается и ответа ты не получаешь, иначе в теле ответа будут нужные данные.
    Для твоего случая, ставь таймаут побольше, например, 300 - ждешь 5 минут.
    Лучше не ставить бесконечное время ожидания, т.к. что-то может сломаться, а ты об этом не узнаешь и по-факту будешь ожидать ничего
    Ответ написан
    2 комментария
  • Как собрать JSON из класса?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Ты не инициализируешь основной массив. Это таким образом делается.
    Rootobject rootobject = new Rootobject();
    rootobject.keyboard = new string[2][];
    Ответ написан
    1 комментарий
  • Как сформировать Json из массива?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Ты записываешь данные в неинициализированные массив.
    Т.е. у тебя каждый элемент внешнего массива - null.

    Просто инициализируй их:
    var keyboard = new Inline_Keyboard[3][];
    keyboard[0] = new Inline_Keyboard[1];
    keyboard[1] = new Inline_Keyboard[2];
    keyboard[2] = new Inline_Keyboard[2];
    rootobject.inline_keyboard = keyboard;


    P.S. но лучше замени на List
    Ответ написан
    6 комментариев
  • Как пофиксить ошибку сериализации в XML?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Попробуй в классе ScenarioManeger Chapter[] заменить на List<Chapter>.
    Скорее всего, при десериализации XML хочет добавить в массив новый элемент, но массив динамически не изменяется, поэтому и возникает ошибка
    Ответ написан
    9 комментариев
  • Почему не находит файл C# в csc?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Проверь, что директория откуда запускаешь - та же самая, что и та, которая этот .cs файл хранит.
    На всякий случай, выполни cd /file/path, где /file/path - полный путь до директории с этим файлом.

    P.S. судя по всему, нужная версия фреймворка у тебя установлена, поэтому хотя бы запускается
    Ответ написан
    Комментировать
  • Как правильно реализовать Coroutine и метод OnMouseDown, чтобы увеличить кол-во очков за нажатие на объекты в течение определенного времени?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Согласно туториалу, таймеры лучше делать через отдельные объекты, а не методы-корутины.
    Ответ написан
    Комментировать
  • Unity не считывает курсор мыши. Что делать?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Где присвоение значения полю Lookpoint?
    Ответ написан
    Комментировать
  • Как записать управляемый объект делегата, в неуправляемую память, или какие есть решения?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Объекты этой структуры будут в неуправляемой памяти, То есть зафиксированы.

    Неуправляемые объекты не подвергаются процессу сбора мусора - они вообще не проверяются.
    Вот и происходит следующее:
    1. Имеется массив объектов неуправляемой памяти
    2. В каждом объекте имеется ссылка на объект управляемой памяти
    3. GC запускается и т.к. неуправляемые объекты не проверяются, то объекты на которые ссылаются неправляемые исчезают, т.к. ссылок на них, возможно, больше не осталось.

    Попробуй:
    - Вызвать GC.KeepAlive на ссылках управляемой памяти (кол-беках)
    var funces = new Fun[];
    // Код
    GC.KeepAlive(funces);

    - Либо сохраняй массив объектов управляемой памяти вместе с целевым массивом, чтобы переменная с этим массивом хранилась в этом же методе и на нем вызови GC.KeepAlive (иначе область видимости ограничивается методом, в котором они создались). Примерно так:
    var (arr, managedObjects) = Create(funces);
    // Код
    GC.KeepAlive(managedObjects);

    - Либо, попробуй перед началом работы метода запрещать сборку мусора - GC.TryStartNoGCRegion/GC.EndNoGCRegion

    Самое что непонятное. хоть вопрос на что где когда отправляй, почему то ломается то нет.

    Во-первых, работа GC не детерминирована - он может запуститься в любой момент.
    Во-вторых, DEBUG или RELEASE режимы компиляции добавляют различные оптимизации и т.д. в процесс работы.
    В-третьих, при подключенном дебагере все локальные переменные не будут собраны GC, т.к. на них неявно появляются указатели.
    Ответ написан
  • Есть ли курсы/книги по автотестированию Selenium + C#?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Ответ написан
    Комментировать