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

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Порты:
    1. 80 – http
    2. 443 – https


    Программа
    using System.Net;
    
    namespace ConsoleApp;
    
    internal class Program
    {
        private const int SUCCESS = 0;
        private const int COMMAND_LINE_ARGS_ARE_NOT_SPECIFIED = 1;
        private const int EXCEPTION_THROWN = 2;
    
        private static Task<int> Main(string[] args)
        {
            return new Program().Run(args);
        }
    
        private async Task<int> Run(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Not enough positional command-line arguments specified!");
                return COMMAND_LINE_ARGS_ARE_NOT_SPECIFIED;
            }
    
            try
            {
                foreach (string hostName in args)
                {
                    IPHostEntry hostEntry = await Dns.GetHostEntryAsync(hostName);
                    DisplayHost(hostEntry);
                }
    
                return SUCCESS;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return EXCEPTION_THROWN;
            }
        }
    
        private void DisplayHost(IPHostEntry hostEntry)
        {
            Console.WriteLine(hostEntry.HostName);
            foreach (var ipAddress in hostEntry.AddressList)
            {
                Console.WriteLine(ipAddress);
            }
            Console.WriteLine("---");
        }
    }


    ConsoleApp.csproj
    <Project Sdk="Microsoft.NET.Sdk">
    
        <PropertyGroup>
            <OutputType>Exe</OutputType>
            <TargetFramework>net6.0</TargetFramework>
            <ImplicitUsings>enable</ImplicitUsings>
            <Nullable>enable</Nullable>
        </PropertyGroup>
    
    </Project>
    Ответ написан
    2 комментария
  • Xamarin — есть ли книги на русском?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Usmanakk, в дополнение к предложенной выше книге по Xamarin:
    Android. Программирование для профессионалов. 4-е издание | Гарднер Брайан, Марсикано Кристин

    Книги в первую очередь ищи на Amazon (на английском). Потом уже их перевод.

    Если знаешь C#, то Kotlin во-первых, покажется даже красивее и удобнее, чем C#, во-вторых там ничего в нём нет такого, что бы нужно было прям изучать месяцами. Я за пару дней понял, что к чему и уже по этой книге нормально писал примеры (на самом деле я сразу писал их, но по мелочи то там, то там разбирался с Kotlin). Чтобы понимать, что там к чему, в Android Studio можно посмотреть байт-код Kotlin и декомпилировать его в Java. A Java 1 в 1 C# (грубо говоря, разница конечно есть и не только в синтаксисе). Открываешь файл с Kotlin кодом, дальше Tools - Kotlin - Show Kotlin Bytecode. В открывшемся окне кнопка Decompile. Android Studio удобно ставить и обновлять через JetBrains Toolbox

    Всё сделаешь по книге, скорее всего, Xamarin и не понадобится, а если понадобится, то будет легко потому что ты знаешь как писать нативно приложения под Android. Да, сейчас уже зарелизили MAUI.

    https://ttu.github.io/kotlin-is-like-csharp/ (сравнение как сделать на Kotlin и то же самое на C#)
    https://developer.android.com/docs
    Ответ написан
    Комментировать
  • Какая книга лучше?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Можно смело начинать учить по книге с C# 9
    Скорее всего, это все отличия (см. по ссылкам). В книге по 9 версии не будет информации о версиях 10 и 11
    Новые возможности C# 10
    Новые возможности C# 11
    Ответ написан
    Комментировать
  • Как можно исправить код для поиска квадратных уравнений?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    using static ConsoleApp.ConsoleInput;
    
    namespace ConsoleApp;
    
    public class Program
    {
        static void Main(string[] args)
        {
            new Program().Run(args);
        }
    
        private void Run(string[] args)
        {
            Console.WriteLine("Введите данные уравнения"); // Введите данные уравнения
            double a = RequestUserInputAsDouble("Введите число a:"); // Введите а
            double b = RequestUserInputAsDouble("Введите число b:"); // Введите b
            double c = RequestUserInputAsDouble("Введите число c:"); // Введите c
            Console.WriteLine("Ваше уравнение: " + a + "x^2 + " + b + "x + " + c + " = 0");
            double discriminant = CalculateDiscriminant(a, b, c);
    
            if (discriminant < 0) // Условие, если Дискриминант < 0
            {
                Console.WriteLine("Нет решений, т.к D < 0 "); // Вывод ответа
            }
            else if (discriminant > 0) // // Условие, если Дискриминант > 0
            {
                double x1 = (-b + Math.Sqrt(discriminant)) / (2 * a); // Обьявление переменной х1 и решение
                double x2 = (-b - Math.Sqrt(discriminant)) / (2 * a); // Обьявление переменной х2 и решение
                Console.WriteLine("Ваш ответ: x1 = " + x1 + " x2 = " + x2); // Вывод ответа
            }
            else // (D == 0)  Условие, если Дискриминант = 0
            {
                double x1 = (-b + Math.Sqrt(0)) / (2 * a); // Обьявление переменной х1 и решение
                double x2 = x1; // Обьявление переменной х2 и решение
                Console.WriteLine("Ваш ответ: x2 = x1 = " + x1); // Вывод ответа
            }
        }
    
        private double CalculateDiscriminant(double a, double b, double c)
        {
            // Вычисление переменной Дискриминант
            return b * b - (4 * a * c);
        }
    }


    Класс, который позволяет запросить ввод пользователя и если пользователь ввёл неверные данные, которые нельзя конвертировать в целевой тип данных, то ввод снова запрашивается у пользователя.
    using System.Globalization;
    
    namespace ConsoleApp;
    
    internal static class ConsoleInput
    {
        private static readonly CultureInfo CommaCulture =
            new(CultureInfo.InvariantCulture.LCID)
            {
                NumberFormat = { NumberDecimalSeparator = "," }
            };
        private static readonly CultureInfo PointCulture =
            new(CultureInfo.InvariantCulture.LCID)
            {
                NumberFormat = { NumberDecimalSeparator = "." }
            };
    
    
        /// <summary>
        /// Запросить ввод у пользователя. Если ввод нельзя конвертировать в целевой тип,
        /// то ввод будет запрошен повторно. Это обобщённый метод, позволящий реализовать 
        /// несколько других методов, требующих ввод в определённом формате.
        /// </summary>
        /// <typeparam name="TResult">
        /// Тип результата, который ожидается от метода конвертации.
        /// </typeparam>
        /// <param name="tryConvert">Ссылка на метод конвертации.</param>
        /// <param name="message">
        /// Сообщение, которое будет показано пользователю каждый новый запрос ввода значения.
        /// </param>
        /// <returns></returns>
        private static TResult RequestUserInput<TResult>(
            Func<string, (bool, TResult)> tryConvert, string? message = null)
            where TResult : struct
        {
            TResult result;
            while (true)
            {
                if (!string.IsNullOrWhiteSpace(message))
                {
                    Console.WriteLine(message);
                }
    
                string? line = Console.ReadLine();
                if (!string.IsNullOrWhiteSpace(line))
                {
                    var (success, convertedValue) = tryConvert(line);
                    if (success)
                    {
                        result = convertedValue;
                        break;
                    }
                }
            }
    
            return result;
        }
    
        /// <summary>
        /// Запросить у пользователя ввод числа типа double.
        /// Допускается в качестве разделителя "," и ".".
        /// </summary>
        /// <param name="message">
        /// Сообщение, которое будет показано пользователю каждый новый запрос ввода значения.
        /// </param>
        /// <returns></returns>
        public static double RequestUserInputAsDouble(string? message = null)
        {
            return RequestUserInput(userInput =>
            {
                CultureInfo culture = CultureInfo.InvariantCulture;
                if (userInput.Contains(",")) culture = CommaCulture;
                if (userInput.Contains(".")) culture = PointCulture;
                return double.TryParse(
                    userInput, NumberStyles.Float, culture, out var result)
                    ? (true, result)
                    : (false, 0d);
            }, message);
        }
    
        // И другие типы в том же духе
        public static int RequestUserInputAsInt32(string? message = null)
        {
            return RequestUserInput(userInput =>
                    int.TryParse(userInput, out var result)
                        ? (true, result)
                        : (false, 0),
                message);
        }
    }
    Ответ написан
    Комментировать
  • Как с одного массива данных внести данные из другого?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Если я всё правильно понял, то вот:

    Исходные данные:
    FirstReportInvoiceDal[] firstReportInvoice =
    {
        new () { Id = 1, Number = "" },
        new () { Id = 2, Number = "" },
        new () { Id = 3, Number = "" },
        new () { Id = 4, Number = "" },
        new () { Id = 5, Number = "" },
    };
    SecondReportInvoiceDal[] secondReportInvoice =
    {
        new () { FirstReportId = 1, Number = "1111N" },
        new () { FirstReportId = 2, Number = "2222N" },
        new () { FirstReportId = 3, Number = "3333N" },
        new () { FirstReportId = 4, Number = "4444N" },
        new () { FirstReportId = 5, Number = "5555N" },
    };


    Вывод:
    Id: 1, Number: 1111N
    Id: 2, Number: 2222N
    Id: 3, Number: 3333N
    Id: 4, Number: 4444N
    Id: 5, Number: 5555N


    namespace ConsoleApp;
    
    class Program
    {
        public static void Main(string[] args)
        {
            FirstReportInvoiceDal[] firstReportInvoice =
            {
                new () { Id = 1, Number = "" },
                new () { Id = 2, Number = "" },
                new () { Id = 3, Number = "" },
                new () { Id = 4, Number = "" },
                new () { Id = 5, Number = "" },
            };
            SecondReportInvoiceDal[] secondReportInvoice =
            {
                new () { FirstReportId = 1, Number = "1111N" },
                new () { FirstReportId = 2, Number = "2222N" },
                new () { FirstReportId = 3, Number = "3333N" },
                new () { FirstReportId = 4, Number = "4444N" },
                new () { FirstReportId = 5, Number = "5555N" },
            };
    
            ReportRow[] rows = CreateReportRows(firstReportInvoice, secondReportInvoice);
            Display(rows);
        }
    
        private static void Display(IEnumerable<ReportRow> rows)
        {
            foreach (ReportRow row in rows)
            {
                Console.WriteLine(row);
            }
        }
    
        static ReportRow[] CreateReportRows(FirstReportInvoiceDal[] firstReportInvoice,
            SecondReportInvoiceDal[] secondReportInvoice)
        {
            // Для быстрого поиска делаем словарь с ключом SecondReportInvoiceDal.FirstReportId,
            // который соответствует ключу FirstReportInvoiceDal.Id.
            var secondReportSet = secondReportInvoice.ToDictionary(x => x.FirstReportId);
    
            // Для каждого firstReportInvoice сделать трансформацию (LINQ метод Select)
            return firstReportInvoice.Select(x =>
            {
                var row = new ReportRow
                {
                    Id = x.Id,
                    Number = secondReportSet[x.Id].Number
                };
                return row;
                // Вызываем ToArray, чтобы запустилось выполнение трансформации в методе Select.
                // И чтобы в принципе мы вернули данные, а не итератор.
            }).ToArray();
        }
    }
    
    class FirstReportInvoiceDal
    {
        public int Id { get; init; }
    
        public string Number { get; init; }
    }
    
    class SecondReportInvoiceDal
    {
        public int FirstReportId { get; init; }
    
        public string Number { get; init; }
    }
    
    class ReportRow
    {
        public int Id { get; init; }
    
        public string Number { get; init; }
    
        public override string ToString()
        {
            return $"Id: {Id}, Number: {Number}";
        }
    }
    Ответ написан
    1 комментарий
  • Подсчет гласных букв. Почему ошибки?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Вот как-то так можно. Зачем здесь объявление алфавита? Да теперь его можно копипастить в каждый проект, что удобно. И соревнований по максимальной краткости, вроде бы, не объявляли.

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
      </PropertyGroup>
    
    </Project>


    using System.Collections.ObjectModel;
    using System.Globalization;
    
    namespace VowelsCount;
    
    public class Program
    {
        static void Main(string[] args)
        {
            var letters = new List<Letter> {
                new ('а', LetterType.Vowel),
                new ('б', LetterType.Consonant),
                new ('в', LetterType.Consonant),
                new ('г', LetterType.Consonant),
                new ('д', LetterType.Consonant),
                new ('е', LetterType.Vowel),
                new ('ё', LetterType.Vowel),
                new ('ж', LetterType.Consonant),
                new ('з', LetterType.Consonant),
                new ('и', LetterType.Vowel),
                new ('й', LetterType.Consonant),
                new ('к', LetterType.Consonant),
                new ('л', LetterType.Consonant),
                new ('м', LetterType.Consonant),
                new ('н', LetterType.Consonant),
                new ('о', LetterType.Vowel),
                new ('п', LetterType.Consonant),
                new ('р', LetterType.Consonant),
                new ('с', LetterType.Consonant),
                new ('т', LetterType.Consonant),
                new ('у', LetterType.Vowel),
                new ('ф', LetterType.Consonant),
                new ('х', LetterType.Consonant),
                new ('ц', LetterType.Consonant),
                new ('ч', LetterType.Consonant),
                new ('ш', LetterType.Consonant),
                new ('щ', LetterType.Consonant),
                new ('ъ', LetterType.Consonant),
                new ('ы', LetterType.Vowel),
                new ('ь', LetterType.Consonant),
                new ('э', LetterType.Vowel),
                new ('ю', LetterType.Vowel),
                new ('я', LetterType.Vowel)
            };
    
            var alphabet = new Alphabet(letters);
            IReadOnlySet<char> vowels = alphabet.GetVowelSet();
            IReadOnlySet<char> consonants = alphabet.GetConsonantSet();
    
            const string text = "Да мы хотим помочь!!!";
    
            int vowelCounter = 0;
            int consonantCounter = 0;
    
            var vowelResult = new char[text.Length];
            var consonantResult = new char[text.Length];
            var otherSymbolsResult = new char[text.Length];
    
            var ruRu = new CultureInfo("ru-RU");
    
            for (int i = 0; i < text.Length; i++)
            {
                vowelResult[i] = '_';
                consonantResult[i] = '_';
                otherSymbolsResult[i] = '_';
    
                char lowerCaseChar = char.ToLower(text[i], ruRu);
                if (consonants.Contains(lowerCaseChar))
                {
                    ++consonantCounter;
                    consonantResult[i] = text[i];
                }
                else if (vowels.Contains(lowerCaseChar))
                {
                    ++vowelCounter;
                    vowelResult[i] = text[i];
                }
                else
                {
                    otherSymbolsResult[i] = text[i];
                }
            }
    
            Console.WriteLine("Исходная строка для подсчёта:");
            Console.WriteLine(text);
            Console.WriteLine("=========");
            Console.WriteLine(vowelResult);
            Console.WriteLine(consonantResult);
            Console.WriteLine(otherSymbolsResult);
            Console.WriteLine("=========");
            Console.WriteLine("Кол-во символов в исходной строке: " + text.Length);
            Console.WriteLine("Кол-во гласных: " + vowelCounter);
            Console.WriteLine("Кол-во согласных: " + consonantCounter);
            Console.WriteLine("Кол-во прочих символов: " +
                (text.Length - (vowelCounter + consonantCounter)));
        }
    }
    
    /// <summary>Тип буквы - гласная или согласная.</summary>
    internal enum LetterType
    {
        /// <summary>Гласная.</summary>
        Vowel,
    
        /// <summary>Согласная.</summary>
        Consonant
    }
    
    internal record struct Letter(char letter, LetterType type)
    {
        public LetterType Type { get; init; } = type;
    
        public char Value { get; init; } = letter;
    }
    
    internal class Alphabet
    {
        public IReadOnlyList<Letter> Letters { get; }
    
        public Alphabet(IEnumerable<Letter> letters)
        {
            Letters = letters switch
            {
                IList<Letter> list => new ReadOnlyCollection<Letter>(list),
                _ => new ReadOnlyCollection<Letter>(letters.ToList()),
            };
        }
    
        public IReadOnlyList<char> GetVowelList()
        {
            return Letters
                .Where(letter => letter.Type == LetterType.Vowel)
                .Select(letter => letter.Value)
                .ToList()
                .AsReadOnly();
        }
    
        public IReadOnlySet<char> GetVowelSet()
        {
            return Letters
                .Where(letter => letter.Type == LetterType.Vowel)
                .Select(letter => letter.Value)
                .ToHashSet();
        }
    
        public IReadOnlyList<char> GetConsonantList()
        {
            return Letters
                .Where(letter => letter.Type == LetterType.Consonant)
                .Select(letter => letter.Value)
                .ToList()
                .AsReadOnly();
        }
    
        public IReadOnlySet<char> GetConsonantSet()
        {
            return Letters
                .Where(letter => letter.Type == LetterType.Consonant)
                .Select(letter => letter.Value)
                .ToHashSet();
        }
    }
    Ответ написан
    6 комментариев
  • Функция swap заменить максимальные и минимальные значения массивов?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Обмен местами первых найденных минимальных значений в двух двумерных массивах.
    using System;
    
    namespace ConsoleApp
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                int[,] arrayA = new int[3, 4]
                {
                    {5, 5, 50, 5},
                    {5, 5, 5, 5},
                    {5, 5, 5, 2},
                };
                int[,] arrayB = new int[4, 2]
                {
                    {5, 5},
                    {5, 1},
                    {15, 5},
                    {5, 1},
                };
    
                Console.WriteLine("Array A:");
                Print(arrayA);
    
                Console.WriteLine();
                Console.WriteLine("Array B:");
                Print(arrayB);
    
                Console.WriteLine();
                Console.WriteLine("Array A, first min value position:");
                var (yMinA, xMinA) = FindFirstMinValuePosition(arrayA);
                Print(xMinA, yMinA);
    
                Console.WriteLine();
                Console.WriteLine("Array B, first min value position:");
                var (yMinB, xMinB) = FindFirstMinValuePosition(arrayB);
                Print(xMinB, yMinB);
    
                Console.WriteLine();
                Console.WriteLine("Array A, first max value position:");
                var (yMaxA, xMaxA) = FindFirstMaxValuePosition(arrayA);
                Print(xMaxA, yMaxA);
    
                Console.WriteLine();
                Console.WriteLine("Array B, first max value position:");
                var (yMaxB, xMaxB) = FindFirstMaxValuePosition(arrayB);
                Print(xMaxB, yMaxB);
    
                Swap(arrayA, arrayB, yMinA, xMinA, yMinB, xMinB);
                Swap(arrayA, arrayB, yMaxA, xMaxA, yMaxB, xMaxB);
    
                Console.WriteLine("----");
                Console.WriteLine();
                Console.WriteLine("Array A after two swaps:");
                Print(arrayA);
    
                Console.WriteLine();
                Console.WriteLine("Array B after two swaps:");
                Print(arrayB);
    
                Console.WriteLine();
            }
    
            private static void Swap(int[,] arrayA, int[,] arrayB, int yA, int xA, int yB, int xB)
            {
                int tempB = arrayB[yB, xB];
                arrayB[yB, xB] = arrayA[yA, xA];
                arrayA[yA, xA] = tempB;
            }
    
            private static (int y, int x) FindFirstMinValuePosition(int[,] array)
            {
                if (array is null) throw new ArgumentNullException(nameof(array));
    
                int y = array.GetLength(0);
                int x = array.GetLength(1);
    
                if (y == 0) throw new InvalidOperationException(
                    "The dimension of the array along the Y axis is zero.");
                if (x == 0) throw new InvalidOperationException(
                    "The dimension of the array along the X axis is zero.");
    
                int yResult = 0;
                int xResult = 0;
    
                int minValue = array[0, 0];
                for (int yIndex = 0; yIndex < y; yIndex++)
                {
                    for (int xIndex = 0; xIndex < x; xIndex++)
                    {
                        if (minValue > array[yIndex, xIndex])
                        {
                            yResult = yIndex;
                            xResult = xIndex;
                            minValue = array[yIndex, xIndex];
                        }
                    }
                }
    
                return (yResult, xResult);
            }
    
            private static (int y, int x) FindFirstMaxValuePosition(int[,] array)
            {
                if (array is null) throw new ArgumentNullException(nameof(array));
    
                int y = array.GetLength(0);
                int x = array.GetLength(1);
    
                if (y == 0) throw new InvalidOperationException(
                    "The dimension of the array along the Y axis is zero.");
                if (x == 0) throw new InvalidOperationException(
                    "The dimension of the array along the X axis is zero.");
    
                int yResult = 0;
                int xResult = 0;
    
                int maxValue = array[0, 0];
                for (int yIndex = 0; yIndex < y; yIndex++)
                {
                    for (int xIndex = 0; xIndex < x; xIndex++)
                    {
                        if (maxValue < array[yIndex, xIndex])
                        {
                            yResult = yIndex;
                            xResult = xIndex;
                            maxValue = array[yIndex, xIndex];
                        }
                    }
                }
    
                return (yResult, xResult);
            }
    
            private static void Print(int x, int y)
            {
                Console.WriteLine($"x: {x}, y: {y}");
            }
    
            private static void Print(int[,] array)
            {
                int x = array.GetLength(0);
                int y = array.GetLength(1);
    
                for (int xIndex = 0; xIndex < x; xIndex++)
                {
                    for (int yIndex = 0; yIndex < y; yIndex++)
                    {
                        Console.Write($"{array[xIndex, yIndex]}, ");
                    }
                    Console.WriteLine();
                }
            }
        }
    }


    Вывод программы:
    Array A:
    5, 5, 50, 5,
    5, 5, 5, 5,
    5, 5, 5, 2,
    
    Array B:
    5, 5,
    5, 1,
    15, 5,
    5, 1,
    
    Array A, first min value position:
    x: 3, y: 2
    
    Array B, first min value position:
    x: 1, y: 1
    
    Array A, first max value position:
    x: 2, y: 0
    
    Array B, first max value position:
    x: 0, y: 2
    ----
    
    Array A after two swaps:
    5, 5, 15, 5,
    5, 5, 5, 5,
    5, 5, 5, 1,
    
    Array B after two swaps:
    5, 5,
    5, 2,
    50, 5,
    5, 1,
    Ответ написан
    3 комментария
  • Имя i не существует в текущем контексте?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Не написал в цикле int. Если это "оптимизация", то не нужно заниматься ерундой. Переменная будет видна внутри области видимости, в которой она объявлена, и внутри вложенных областей видимости, так сказать. Снаружи нет.
    for (int i = 0; i < arraySize; i++)
    {
        // Используй всегда скобки. Вот опыт тебя уже научил, что без них ты получил ошибку.
    }


    Код должен выглядеть как-то так, без учёта валидации ввода и запроса по новой. Здесь больше про именование переменных и про наличие фигурных скобок у for.
    // Program.cs
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Введите n");
                int arraySize = int.Parse(Console.ReadLine());
    
                int[] array = new int[arraySize];
                Console.WriteLine("Введите массив А");
    
                for (int i = 0; i < arraySize; i++)
                {
                    array[i] = int.Parse(Console.ReadLine());
                }
    
                int max = array[0];
                for (int i = 0; i < arraySize; i++)
                {
                    if (array[i] > max) 
                        max = array[i];
    
                    Console.Write(array[i] + " ");
                }
                
    
                Console.ReadLine();
            }
        }


    Ещё бы посоветовал избавиться от стремления написать как можно больше кода в одну строку. Это бессмысленное занятие.
    Ответ написан
    1 комментарий
  • Как сделать асинхронный while цикл?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    ConsoleApp\Program.cs
    // See https://aka.ms/new-console-template for more information
    
    await DoWork();
    
    async Task DoWork()
    {
        int counter = 0;
        while (true)
        {
            Console.WriteLine($"TEST {++counter}");
            await Task.Delay(900);
        }
    }


    ConsoleApp\ConsoleApp.csproj
    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
      </PropertyGroup>
    
    </Project>
    Ответ написан
    Комментировать
  • Вопрос про изучение C# – оптимальная методика?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Нормально. Я так и учил C#. Практика важна в этом деле, без неё долго будешь учить. Только я писал WPF приложение. И вообще практика написания больших приложений учит строить архитектуру. Будешь писать код и видеть проблемы в своём проекте. Рефакторить проект. Переписывать его части.
    Ответ написан
    2 комментария
  • C# - плавающий глюк - насколько правильно исправил?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Подпишись на событие FormClosing (если ещё не подписан) и в его обработчике отпишись от обработчиков событий TitleChanged, AddressChanged, LoadingStateChanged:
    public partial class BrowserMain : Form
    {
        public BrowserMain()
        {
            InitializeComponent();
            
            WebBrowser = new ChromiumWebBrowser(
                string.IsNullOrWhiteSpace(address) ? "about:blank" : address)
            {
                // ...
            };
    
            Controls.Add(WebBrowser);
    
            WebBrowser.TitleChanged += WebBrowser_TitleChanged;
            WebBrowser.AddressChanged += WebBrowser_AddressChanged;
            WebBrowser.LoadingStateChanged += webBrowser_DocumentCompleted;
        }
    
        private void BrowserMain_FormClosing(object sender, FormClosingEventArgs e)
        {
           // После вызова этих строк методы WebBrowser_TitleChanged, WebBrowser_AddressChanged
           // и webBrowser_DocumentCompleted не будут выполняться. 
           // Это и не нужно, так как окно закрывается.
            WebBrowser.TitleChanged -= WebBrowser_TitleChanged;
            WebBrowser.AddressChanged -= WebBrowser_AddressChanged;
            WebBrowser.LoadingStateChanged -= webBrowser_DocumentCompleted;
        }
    }
    Ответ написан
    3 комментария
  • С чего начать изучение C#?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Советую заглянуть в базу знаний для .NET разработчиков (будет пополняться)
    Ответ написан
    Комментировать
  • Как работать с wpf анимацией?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    При её нажатии на кнопку снизу всплывает надпись и исчезает. В контрол можно поместить, что угодно, не только текст. Остальной код в комментариях.

    MainWindow.xaml.cs
    using System.Windows;
    
    namespace Notification
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void OnButtonClick(object sender, RoutedEventArgs e)
            {
                _notification.Activate();
            }
        }
    }


    Controls/NotificationControl.cs
    using System.Windows;
    using System.Windows.Controls;
    
    namespace Notification.Controls
    {
        public class NotificationControl : ContentControl
        {
            public NotificationControl()
            {
                DefaultStyleKey = typeof(NotificationControl);
            }
    
            public void Activate()
            {
                VisualStateManager.GoToState(this, "Default", false);
                VisualStateManager.GoToState(this, "Activated", true);
            }
        }
    }


    Resources/Styles.xaml
    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:Notification.Controls">
    
        <KeyTime x:Key="OffsetYKeyTime">0:0:0.8</KeyTime>
        <KeyTime x:Key="OpacityDelayKeyTime">0:0:1.8</KeyTime>
        <KeyTime x:Key="VisibilityDelayKeyTime">0:0:2.2</KeyTime>
        <Style TargetType="controls:NotificationControl">
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="HorizontalAlignment" Value="Stretch" />
            <Setter Property="VerticalAlignment" Value="Stretch" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="controls:NotificationControl">
                        <Border
                            x:Name="RootElement"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Opacity="0"
                            Visibility="Collapsed">
                            <ContentPresenter
                                x:Name="ContentPresenter"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                <ContentPresenter.RenderTransform>
                                    <TransformGroup>
                                        <TranslateTransform />
                                        <RotateTransform />
                                    </TransformGroup>
                                </ContentPresenter.RenderTransform>
                            </ContentPresenter>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Default">
                                        <Storyboard>
    
                                            <DoubleAnimationUsingKeyFrames
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)">
                                                <EasingDoubleKeyFrame
                                                    KeyTime="0:0:0"
                                                    Value="0">
                                                </EasingDoubleKeyFrame>
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimationUsingKeyFrames
                                                Storyboard.TargetName="RootElement"
                                                Storyboard.TargetProperty="Opacity">
                                                <EasingDoubleKeyFrame
                                                    KeyTime="0:0:0"
                                                    Value="1">
                                                </EasingDoubleKeyFrame>
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="RootElement"
                                                Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
    
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Activated">
                                        <Storyboard>
    
                                            <DoubleAnimationUsingKeyFrames
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)">
                                                <EasingDoubleKeyFrame
                                                    KeyTime="0:0:0"
                                                    Value="0">
                                                    <EasingDoubleKeyFrame.EasingFunction>
                                                        <QuadraticEase EasingMode="EaseOut" />
                                                    </EasingDoubleKeyFrame.EasingFunction>
                                                </EasingDoubleKeyFrame>
                                                <EasingDoubleKeyFrame
                                                    KeyTime="{StaticResource OffsetYKeyTime}"
                                                    Value="-80">
                                                    <EasingDoubleKeyFrame.EasingFunction>
                                                        <QuadraticEase EasingMode="EaseOut" />
                                                    </EasingDoubleKeyFrame.EasingFunction>
                                                </EasingDoubleKeyFrame>
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimationUsingKeyFrames
                                                Storyboard.TargetName="RootElement"
                                                Storyboard.TargetProperty="Opacity">
                                                <EasingDoubleKeyFrame
                                                    KeyTime="0:0:0"
                                                    Value="1">
                                                    <EasingDoubleKeyFrame.EasingFunction>
                                                        <QuadraticEase EasingMode="EaseInOut" />
                                                    </EasingDoubleKeyFrame.EasingFunction>
                                                </EasingDoubleKeyFrame>
                                                <EasingDoubleKeyFrame
                                                    KeyTime="{StaticResource OpacityDelayKeyTime}"
                                                    Value="0">
                                                    <EasingDoubleKeyFrame.EasingFunction>
                                                        <QuadraticEase EasingMode="EaseInOut" />
                                                    </EasingDoubleKeyFrame.EasingFunction>
                                                </EasingDoubleKeyFrame>
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="RootElement"
                                                Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                                <DiscreteObjectKeyFrame KeyTime="{StaticResource VisibilityDelayKeyTime}">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
    
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
    Ответ написан
  • Как в C# (.NET) задать значение возвращаемого методом значения через ref, используя reflection?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    using System;
    using System.Diagnostics;
    using System.Reflection;
    
    namespace ConsoleApp
    {
        class Program
        {
            private delegate ref int GetMaxNumber(ref int value1, ref int value2);
    
            static void Main(string[] args)
            {
                int value1 = 5;
                int value2 = 10;
                var instance = new Something();
    
                MethodInfo? methodInfo = typeof(Something).GetMethod(
                    nameof(Something.GetMax), BindingFlags.Public | BindingFlags.Instance);
                Debug.Assert(methodInfo is not null);
                var setNumber = (GetMaxNumber)Delegate.CreateDelegate(typeof(GetMaxNumber), instance, methodInfo);
    
                setNumber.Invoke(ref value1, ref value2) = 50;
    
                Console.WriteLine($"{nameof(value1)}: {value1}, {nameof(value2)}: {value2}");
            }
        }
    
        public class Something
        {
            public ref int GetMax(ref int left, ref int right)
            {
                if (left > right)
                {
                    return ref left;
                }
    
                return ref right;
            }
        }
    }


    Проверял на
    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
        <Nullable>enable</Nullable>
      </PropertyGroup>
    
    </Project>
    Ответ написан
    Комментировать
  • Как сделать таймер после которого запустится код?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    using System;
    using System.Diagnostics;
    using System.Windows.Forms;
    
    namespace WinFormsApp
    {
        public partial class MainForm : Form
        {
            private readonly Timer _timer;
            private int _counter;
    
            public MainForm()
            {
                InitializeComponent();
    
                _timer = new Timer();
                _timer.Interval = 500;
                _timer.Tick += OnTimerTick;
            }
    
            private void OnFormLoad(object sender, EventArgs e)
            {
                _timer.Start();
            }
    
            private void OnTimerTick(object sender, EventArgs e)
            {
                _label.Text = $"{nameof(OnTimerTick)}. {(++_counter).ToString()}";
            }
        }
    }
    Ответ написан
  • С чего начать новичку в изучении c# для gamedev?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Для C# (пишется с большой буквы) установи cреду разработки Visual Studio Community (ссылка).

    В первую очередь тебе нужно выучить C#. Чтобы у тебя дошло до автоматизма написание кода. Первое время ты будешь сильно подвисать на каждой мелочи. Простейшие ошибки будут ставить в тупик. Наверняка, сюда задавать вопросы, что нормально. Это дело не быстрое, невозможно с полного нуля за неделю всё выучить, уйдёт от полугода. И нужно на это будет тратить много времени, желательно даже каждый день. Без знания языка и умения писать в стиле ООП простые приложения я уверен, что в Unity делать нечего.

    Рекомендую создать Решение (Solution) на C# в Visual Studio и в него добавлять проекты по темам из книги.
    Пример проектов в решении:
    Изучение C# (.sln)
    1. Переменные, циклы (.csproj)
    2. Классы (.csproj)
    3. Наследование (.csproj)
    4. Делегаты и события (.csproj)
    Только проекты называй по-английски.
    Прочитал главу, сделал примеры из книги, написал везде комментарии с пояснениями. Делай так, чтобы потом можно было вернуться к этим проектам и быстро вспомнить, что забылось. После того как ты будешь много времени тратить на обучение и чтение книги, у тебя всё лучше и лучше будут запоминаться детали языка. Именно за счёт траты большого кол-ва времени и обучения на длительном промежутке времени всё и выучится само. Я не зубрил ничего почти.

    Очень хорошее объяснение по C# здесь. Сразу скажу, уроки очень старые, но очень хорошие (там про платформу .NET Framework, но ничего нет про .NET Core, а теперь уже просто .NET (начиная с 5) и многого другого). Можно посмотреть эти уроки, после них начать читать книгу по C#, пусть из уроков много будет знакомо, но, скорее всего, в книге ты узнаешь новые детали и учить будет легче.

    Ещё такой курс более современный, его не смотрел.

    Кстати, чтобы не терять интерес, ты конечно можешь установить себе Unity, найти уроки по созданию 2D платформера, даже начать делать по урокам первую игру, но я тебе советую периодически как посидел над Unity возвращаться к книге и читать её дальше и так пока всю не прочитаешь. Я так и учил C#. Писал приложение, так как именно это было интересно, и периодически возвращался к книге.

    Алгоритмы. Можешь почитать хотя бы что-то простое для начала. Например,
    Алгоритмы. Вводный курс | Кормен Томас Х.

    https://qna.habr.com/q/848533#answer_1745621

    Книги есть такие:
    C# 9.0. Справочник. Полное описание языка (ссылка)
    Язык программирования C# 7 и платформы .NET и .NET Core | Джепикс Филипп, Троелсен Эндрю (ссылка)

    Возможно даже
    C# для чайников | Мюллер Джон Поль, Семпф Билл (здесь C# 7.0). ISBN: 978-5-907144-43-9
    Ответ написан
    7 комментариев
  • Проверить наличие элемента в json?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Сделай свойство Nullable и если оно будет null, значит значение не пришло совсем. Думаю, это самый простой вариант, если тебя не устраивает значение 0 по умолчанию для типа int, которое будет таковым, если даже не пришло значение того свойства.

    public class Competitive
    {
        [JsonProperty("CurrentSeasonGamesNeededForRating")]
        public int? CurrentSeasonGamesNeededForRating { get; set; }
    
        [JsonProperty("SeasonalInfoBySeasonID")]
        public object SeasonalInfoBySeasonID { get; set; }
    }
    Ответ написан
    1 комментарий
  • Почему при запросе объекта стиля, получается null?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Как вариант, можно создать окно, в котором задать заранее определённые стили, задать им TargetType и это надо сделать. Задать каждому стилю уникальный ключ. Создать в Code Behind окна свойство с текущим стилем и его менять. К этому свойству можно прибиндиться TextBlock(ом). Можно всё это сделать красивее и т.д., но суть из примера будет ясна, думаю.

    Вот можно посмотреть как здесь предлагают Changing the styles at runtime in WPF

    <Window
        x:Class="Monitor.SomeWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:Monitor"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="SomeWindow"
        Width="800"
        Height="450"
        mc:Ignorable="d">
        <Window.Resources>
            <Style
                x:Key="BaseFontFamily"
                TargetType="TextBlock">
                <Setter Property="FontSize" Value="90" />
            </Style>
            <Style
                x:Key="Numbers1Style"
                BasedOn="{StaticResource BaseFontFamily}"
                TargetType="TextBlock">
                <Setter Property="Foreground" Value="LightCoral" />
            </Style>
            <Style
                x:Key="Numbers2Style"
                BasedOn="{StaticResource BaseFontFamily}"
                TargetType="TextBlock">
                <Setter Property="Foreground" Value="Bisque" />
            </Style>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <TextBlock
                Grid.Row="0"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Style="{Binding TimeBlockStyle, RelativeSource={RelativeSource AncestorType=local:SomeWindow}}"
                Text="{Binding Path=RightTeam.TeamCounter, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
            <Button
                Grid.Row="1"
                Click="OnButtonClick" />
        </Grid>
    </Window>


    public partial class SomeWindow : Window
    {
        public static readonly DependencyProperty TimeBlockStyleProperty = DependencyProperty.Register(
            nameof(TimeBlockStyle), typeof(Style), typeof(SomeWindow), new PropertyMetadata(default(Style)));
    
        public Style TimeBlockStyle
        {
            get { return (Style)GetValue(TimeBlockStyleProperty); }
            set { SetValue(TimeBlockStyleProperty, value); }
        }
    
        public SomeWindow()
        {
            InitializeComponent();
            TimeBlockStyle = (Style)Resources["Numbers1Style"];
        }
    
        private void OnButtonClick(object sender, RoutedEventArgs e)
        {
            TimeBlockStyle = (Style)Resources["Numbers2Style"];
        }
    }
    Ответ написан
    5 комментариев
  • Как пeредать const char* в c++ фунцию из c#?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Ответ написан
    Комментировать
  • Как мне это реализовать в List?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Только вот использовать LINQ нужно с осторожностью. Лично я бы вообще не использовал его в том же Update или любом другом месте, где часто вызывается код.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;
    
    [System.Serializable]
    public class TestEvent
    {
        [SerializeField] private int _b;
    
        public int B => _b;
    }
    
    public class TestScript : MonoBehaviour
    {
        [SerializeField] private List<TestEvent> _testEvents;
    
        private int a = 3;
    
        void Start()
        {
            var events = _testEvents
                .Where(item => item.B == a)
                .ToArray();
        }
    }


    Тоже самое, но без LINQ. Чисто показать принцип, так как это элементарная задача, а ты этого не сделал, значит нужно учиться. Если кол-во элементов в List _testEvents небольшое всегда, я бы ещё создавал var results = new List(); с указанием capacity равному _testEvents.Count. То есть так var results = new List(_testEvents.Count);
    public class TestScript : MonoBehaviour
    {
        [SerializeField] private List<TestEvent> _testEvents;
    
        private int a = 3;
    
        void Start()
        {
            var events = GetEvents(_testEvents, item => item.B == a);
        }
    
        private static List<TestEvent> GetEvents(
            IEnumerable<TestEvent> testEvents, Func<TestEvent, bool> predicate)
        {
            var results = new List<TestEvent>();
            foreach (var item in testEvents)
            {
                if (predicate(item))
                {
                    results.Add(item);
                }
            }
            return results;
        }
    }


    Продублирую решение из комментариев:
    public class TestScript : MonoBehaviour
    {
        [SerializeField] private List<TestEvent> _testEvents;
    
        private int a = 3;
    
        void Start()
        {
            var element = GetFirstOrDefault(_testEvents, item => item.B == a);
            if (element is not null)
            {
                c = element.c;
                r = element.r;
                u = element.u;
            }
        }
    
        // Если совпадение не найдено, то вернуть значение по умолчанию.
        private static T GetFirstOrDefault<T>(IEnumerable<T> items, Func<T, bool> predicate)
        {
            foreach (var item in items)
            {
                if (predicate(item))
                {
                    return item;
                }
            }
    
            return default;
        }
    }
    Ответ написан