Как разобрать строку на обнуляемое int

Я хочу преобразовать строку в обнуляемое int в C#. т.е. Я хочу вернуть либо значение int строки, либо значение null, если оно не может быть проанализировано.

Я как бы надеялся, что это сработает

int? val = stringVal as int?;

Но это не сработает, поэтому я делаю это сейчас так: я написал этот метод расширения

public static int? ParseNullableInt(this string value)
{
    if (value == null || value.Trim() == string.Empty)
    {
        return null;
    }
    else
    {
        try
        {
            return int.Parse(value);
        }
        catch
        {
            return null;
        }
    }
}   

Есть ли лучший способ сделать это?

Обновлено: Спасибо за предложения TryParse, я знал об этом, но это сработало примерно так же. Мне больше интересно узнать, есть ли встроенный метод фреймворка, который будет анализировать непосредственно в int, допускающий значение NULL?

Вы можете использовать string.IsNullOrEmpty (value), чтобы сделать строку if более четкой.

Özgür Kaplan 29.02.2012 12:36

Рассмотрите возможность использования универсального преобразования stackoverflow.com/questions/773078/…

Michael Freidgeim 16.06.2016 01:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
316
2
177 497
21
Перейти к ответу Данный вопрос помечен как решенный

Ответы 21

Ответ принят как подходящий

int.TryParse, наверное, немного проще:

public static int? ToNullableInt(this string s)
{
    int i;
    if (int.TryParse(s, out i)) return i;
    return null;
}

Редактировать @Glenn int.TryParse "встроен в структуру". Это и int.Parse - это способ то для синтаксического анализа строк в целые числа.

на одну строку меньше: return Int32.TryParse (s, out i)? я: ноль;

Chris Shouts 23.10.2009 17:31

Я определенно предпочитаю этот способ TryParse

Bent Rasmussen 11.03.2010 18:32

Я собирался опубликовать пример, указывающий на то, что возникнет исключение NullReferenceException, если строка будет нулевой. Вместо этого я узнал кое-что интересное о методах расширения. строка parseOne = "1"; int? resultOne = parseOne.ToNullableInt32 (); System.Diagnostics.Debug.Assert (resultOne == 1); строка parseEmpty = строка.Empty; int? resultEmpty = parseEmpty.ToNullableInt32 (); System.Diagnostics.Debug.Assert (! ResultEmpty.HasValue); строка parseNull = null; int? resultNull = parseNull.ToNullableInt32 (); System.Diagnostics.Debug.Assert (! ResultNull.HasValue);

Daniel Ballinger 09.04.2010 01:02

"a" вернет null, но это не int и должно вызвать исключение.

Arsen Mkrtchyan 19.07.2011 15:37

@Arsen ... именно это и задавал первоначальный вопрос. Посмотрите на его фрагмент кода.

Matt Hamilton 19.07.2011 15:42

@Chris, компилятору не нравится ваш встроенный оператор if (эти типы несовместимы: 'int': 'null'). Мне пришлось изменить его на: return Int32.TryParse (s, out i)? (int?) я: ноль;

death_au 25.01.2012 07:35

Int32 - это просто псевдоним int. Я бы использовал int.TryParse, чтобы используемые типы были согласованы. Если / когда int используется для представления целого числа другой длины в битах (что произошло), Int32 не будет совпадать с int.

Richard Collette 26.11.2012 19:39

return int.TryParse (s, out i)? (int?) я: ноль;

Nick Spreitzer 15.07.2015 18:32

общедоступный статический интервал? _ni (эта строка s) {int i; return int.TryParse (s, out i)? (int?) i: null;}

Martin Capodici 27.01.2016 07:48

@death_au i: новый интервал? ()

ccalboni 30.05.2016 18:23

@ccalboni тоже работает. Как и i : default(int?). Подумав об этом, в ответ он все равно передаст результат на int?, так что, может быть, лучше, если я просто сделаю это? Точно сказать не могу.

death_au 01.06.2016 04:12

Еще одна строка меньше в C# 7 (встроенное объявление i): int.TryParse (s, out int i)? (int?) я: ноль;

Darren 14.09.2016 13:02

общедоступный статический интервал? ToNullableInt (эта строка s) => (int.TryParse (s, out int i))? я: (число?) ноль;

IamIC 20.06.2019 23:35

Использование встроенного объявления и default с выводом типа int.TryParse(s, out var i) ? i as int? : default

Morgan Touverey Quilling 13.12.2019 18:15

Попробуй это:

public static int? ParseNullableInt(this string value)
{
    int intValue;
    if (int.TryParse(value, out intValue))
        return intValue;
    return null;
}

Вы можете сделать это в одной строке, используя условный оператор и тот факт, что вы можете привести null к типу, допускающему значение NULL (две строки, если у вас нет ранее существовавшего int, вы можете повторно использовать для вывода TryParse):

До C# 7:

int tempVal;
int? val = Int32.TryParse(stringVal, out tempVal) ? Int32.Parse(stringVal) : (int?)null;

С обновленным синтаксисом C# 7, который позволяет объявлять выходную переменную в вызове метода, это становится еще проще.

int? val = Int32.TryParse(stringVal, out var tempVal) ? tempVal : (int?)null;

Вы могли бы - но полагаться на побочные эффекты и подобный порядок оценки мерзко, когда вы можете сделать последовательную зависимость очевидной, используя синтаксис Мэтта. Между прочим, для этого и подобных выражений удобно использовать default (int?) Именно для того, чтобы избежать ошибок вывода типов, которые проистекают из нетипизированной природы null, без необходимости вставки приведений, которые могут фактически выполнять код.

Eamon Nerbonne 31.05.2010 19:38

Я думаю, это зависит от вашего взгляда на условный оператор. Моя ментальная модель состоит в том, что это в значительной степени синтаксический сахар для эквивалента if-else, и в этом случае моя версия и версия Мэтта близки к идентичности, причем он более явный, моя более cmopact.

McKenzieG1 02.06.2010 00:48

Здесь нет побочного эффекта порядка оценки. Все шаги четко упорядочены и правильны.

Jon Hanna 22.03.2011 17:30

вернуть int.TryParse(val, out i) ? i : default(int?);

Bart Calixto 12.12.2013 03:10

@ "Ответ" Барта здесь лучший!

Andre Figueiredo 20.12.2013 15:50

А теперь в C# 6 это может быть одна строка! Int32.TryParse (stringVal, out var tempVal)? tempVal: (число?) ноль;

MerickOWA 01.05.2014 18:23

Просто примечание: C# 6 не поставлялся с этой функцией, поэтому не пытайтесь объявить var inline (stackoverflow.com/questions/31724163/…)

chris84948 10.08.2016 18:43

В C# 7 есть, и я пояснил ответ, чтобы показать синтаксис до и после 7.

krillgar 01.11.2017 21:13

Вы должны никогда использовать исключение, если вам не нужно - накладные расходы ужасны.

Варианты TryParse решают проблему - если вы хотите проявить творческий подход (чтобы ваш код выглядел более элегантно), вы, вероятно, могли бы что-то сделать с помощью метода расширения в 3.5, но код будет более или менее таким же.

[Обновлено для использования современного C# согласно предложению @ sblom]

У меня была эта проблема, и я закончил с этим (в конце концов, if и 2 return - это так уж много!):

int? ToNullableInt (string val)
    => int.TryParse (val, out var i) ? (int?) i : null;

Если серьезно, постарайтесь не смешивать int, ключевое слово C#, с Int32, являющимся типом BCL .NET Framework - хотя это работает, код просто выглядит беспорядочным.

Не совсем уверен, что это на самом деле приведет к чему-то, что лучше работает после компиляции.

BuZz 05.11.2013 20:15

Еще более кратко в C# 7: удалите строку int i; и просто перейдите к return int.TryParse (val, out var i) ? (int?) i : null;

sblom 02.03.2017 21:53

Так что для полноты ;-) int? ParseNInt (string val) => int.TryParse (val, out var i) ? (int?) i : null;

Duckboy 02.06.2017 13:19

С C# 6 это может быть сокращено до 1 строки: return int.TryParse (value, out var result)? результат: (int?) null;

MeanGreen 12.01.2018 10:38

I'm more interested in knowing if there is a built-in framework method that will parse directly into a nullable int?

Нет.

Считаете ли вы это прямым подходом? stackoverflow.com/a/6474962/222748

Michael 29.11.2011 03:28

Используя делегаты, следующий код может обеспечить возможность повторного использования, если вам потребуется синтаксический анализ, допускающий значение NULL, для более чем одного типа структуры. Я показал здесь обе версии .Parse () и .TryParse ().

Это пример использования:

NullableParser.TryParseInt(ViewState["Id"] as string);

И вот код, который приведет вас туда ...

public class NullableParser
  {
    public delegate T ParseDelegate<T>(string input) where T : struct;
    public delegate bool TryParseDelegate<T>(string input, out T outtie) where T : struct;
    private static T? Parse<T>(string input, ParseDelegate<T> DelegateTheParse) where T : struct
    {
      if (string.IsNullOrEmpty(input)) return null;
      return DelegateTheParse(input);
    }
    private static T? TryParse<T>(string input, TryParseDelegate<T> DelegateTheTryParse) where T : struct
    {
      T x;
      if (DelegateTheTryParse(input, out x)) return x;
      return null;
    }
    public static int? ParseInt(string input)
    {
      return Parse<int>(input, new ParseDelegate<int>(int.Parse));
    }
    public static int? TryParseInt(string input)
    {
      return TryParse<int>(input, new TryParseDelegate<int>(int.TryParse));
    }
    public static bool? TryParseBool(string input)
    {
      return TryParse<bool>(input, new TryParseDelegate<bool>(bool.TryParse));
    }
    public static DateTime? TryParseDateTime(string input)
    {
      return TryParse<DateTime>(input, new TryParseDelegate<DateTime>(DateTime.TryParse));
    }
  }

Я нашел и адаптировал код для класса Generic NullableParser. Полный код есть в моем блоге Обнуляемый TryParse

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace SomeNamespace
{
    /// <summary>
    /// A parser for nullable types. Will return null when parsing fails.
    /// </summary>
    /// <typeparam name = "T"></typeparam>
    ///
    public static class NullableParser<T> where T : struct
    {
        public delegate bool TryParseDelegate(string s, out T result);
        /// <summary>
        /// A generic Nullable Parser. Supports parsing of all types that implements the tryParse method;
        /// </summary>
        /// <param name = "text">Text to be parsed</param>
        /// <param name = "result">Value is true for parse succeeded</param>
        /// <returns>bool</returns>
        public static bool TryParse(string s, out Nullable<T> result)
        {
            bool success = false;
            try
            {
                if (string.IsNullOrEmpty(s))
                {
                    result = null;
                    success = true;
                }
                else
                {
                    IConvertible convertableString = s as IConvertible;
                    if (convertableString != null)
                    {
                        result = new Nullable<T>((T)convertableString.ToType(typeof(T),
                            CultureInfo.CurrentCulture));
                        success = true;
                    }
                    else
                    {
                        success = false;
                        result = null;
                    }
                }
            }
            catch
            {
                success = false;
                result = null;
            }
            return success;
        }
    }
}

404 Не Найдено. просто давать ссылку - не лучшая практика

Dirty-flow 08.01.2013 19:00

извините за это обновление @ Dirty-flow с полным кодом. Лучше поздно, чем никогда :)

John Dauphine 05.03.2016 20:22

Я понимаю, что это старая тема, но не могли бы вы просто:

(Nullable<int>)int.Parse(stringVal);

?

Вы можете, но тогда вы получите исключение, если stringVal имеет неправильный формат. См. Документацию int.Parse: msdn.microsoft.com/en-us/library/b3h1hf19.aspx

Alex 26.01.2011 17:16

Следующее должно работать для любого типа структуры. Он основан на коде Мэтт Манела с форумов MSDN. Как указывает Мерф, обработка исключений может быть дорогостоящей по сравнению с использованием специального метода TryParse для типов.

        public static bool TryParseStruct<T>(this string value, out Nullable<T> result)
            where T: struct 
        {
            if (string.IsNullOrEmpty(value))
            {
                result = new Nullable<T>();

                return true;
            }

            result = default(T);
            try
            {
                IConvertible convertibleString = (IConvertible)value;
                result = new Nullable<T>((T)convertibleString.ToType(typeof(T), System.Globalization.CultureInfo.CurrentCulture));
            }
            catch(InvalidCastException)
            {
                return false;
            }
            catch (FormatException)
            {
                return false;
            }

           return true;
        }

Это были основные тестовые примеры, которые я использовал.

        string parseOne = "1";
        int? resultOne;
        bool successOne = parseOne.TryParseStruct<int>(out resultOne);
        Assert.IsTrue(successOne);
        Assert.AreEqual(1, resultOne);

        string parseEmpty = string.Empty;
        int? resultEmpty;
        bool successEmpty = parseEmpty.TryParseStruct<int>(out resultEmpty);
        Assert.IsTrue(successEmpty);
        Assert.IsFalse(resultEmpty.HasValue);

        string parseNull = null;
        int? resultNull;
        bool successNull = parseNull.TryParseStruct<int>(out resultNull);
        Assert.IsTrue(successNull);
        Assert.IsFalse(resultNull.HasValue);

        string parseInvalid = "FooBar";
        int? resultInvalid;
        bool successInvalid = parseInvalid.TryParseStruct<int>(out resultInvalid);
        Assert.IsFalse(successInvalid);

Старая тема, а как насчет:

public static int? ParseToNullableInt(this string value)
{
     return String.IsNullOrEmpty(value) ? null : (int.Parse(value) as int?);
}

Мне это больше нравится, так как требование, где разбирать null, версия TryParse не выдает ошибку, например. ToNullableInt32 (XXX). Это может привести к нежелательным скрытым ошибкам.

В том-то и дело - если строка не может быть проанализирована на int, она должна вернуть null, а не генерировать исключение.

svick 29.03.2011 17:25

если значение не является числовым, int.Parse выдает исключение, что не то же самое, что возврат null.

an phu 18.03.2016 01:18

Я чувствовал, что должен поделиться своим, более общим.

Использование:

var result = "123".ParseBy(int.Parse);

var result2 = "123".ParseBy<int>(int.TryParse);

Решение:

public static class NullableParse
{
    public static Nullable<T> ParseBy<T>(this string input, Func<string, T> parser)
        where T : struct
    {
        try
        {
            return parser(input);
        }
        catch (Exception exc)
        {
            return null;
        }
    }

    public delegate bool TryParseDelegate<T>(string input, out T result);

    public static Nullable<T> ParseBy<T>(this string input, TryParseDelegate<T> parser)
        where T : struct
    {
        T t;
        if (parser(input, out t)) return t;
        return null;
    }
}

Первая версия работает медленнее, так как требует попытки уловить, но выглядит чище. Если он не будет вызываться много раз с недопустимыми строками, это не так важно. Если производительность является проблемой, обратите внимание, что при использовании методов TryParse вам необходимо указать параметр типа ParseBy, поскольку он не может быть выведен компилятором. Мне также пришлось определить делегат, поскольку ключевое слово out нельзя использовать в Func <>, но, по крайней мере, на этот раз компилятор не требует явного экземпляра.

Наконец, вы можете использовать его и с другими структурами, например, decimal, DateTime, Guid и т. д.

Я считаю, что мое решение - очень чистое и красивое решение:

public static T? NullableParse<T>(string s) where T : struct
{
    try
    {
        return (T)typeof(T).GetMethod("Parse", new[] {typeof(string)}).Invoke(null, new[] { s });
    }
    catch (Exception)
    {
        return null;
    }
}

Это, конечно, общее решение, которое требует только, чтобы аргумент generics имел статический метод «Parse (string)». Это работает для чисел, логических значений, DateTime и т. д.

Glenn Slaven: I'm more interested in knowing if there is a built-in framework method that will parse directly into a nullable int?

Существует этот подход, который будет анализировать непосредственно до обнуляемого int (а не только int), если значение допустимо, как null или пустая строка, но выдает исключение для недопустимых значений, поэтому вам нужно будет перехватить исключение и вернуть значение по умолчанию для таких ситуаций:

public static T Parse<T>(object value)
{
    try { return (T)System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value.ToString()); }
    catch { return default(T); }
}

Этот подход все еще можно использовать для синтаксического анализа, не допускающего значения NULL, а также для анализа, допускающего значение NULL:

enum Fruit { Orange, Apple }
var res1 = Parse<Fruit>("Apple");
var res2 = Parse<Fruit?>("Banana");
var res3 = Parse<int?>("100") ?? 5; //use this for non-zero default
var res4 = Parse<Unit>("45%");

NB: В преобразователе есть метод IsValid, который вы можете использовать вместо захвата исключения (выброшенные исключения действительно приводят к ненужные накладные расходы, если ожидается). К сожалению, он работает только с .NET 4, но все еще существует проблема, когда он не проверяет ваш языковой стандарт при проверке правильных форматов DateTime, см. ошибка 93559.

Я тестировал это для целых чисел, и это намного медленнее, чем int.TryParse ((string) value, out var result)? результат: по умолчанию (число?);

Wouter 21.10.2018 13:04

Все остальные ответы можно забыть - есть отличное универсальное решение: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/

Это позволяет вам писать очень чистый код, например:

string value = null;
int? x = value.ConvertOrDefault();

а также:

object obj = 1;  

string value = null;
int x = 5;
if (value.TryConvert(out x))
    Console.WriteLine("TryConvert example: " + x); 

bool boolean = "false".ConvertOrDefault();
bool? nullableBoolean = "".ConvertOrDefault();
int integer = obj.ConvertOrDefault();
int negativeInteger = "-12123".ConvertOrDefault();
int? nullableInteger = value.ConvertOrDefault();
MyEnum enumValue = "SecondValue".ConvertOrDefault();

MyObjectBase myObject = new MyObjectClassA();
MyObjectClassA myObjectClassA = myObject.ConvertOrDefault();

Это действительно очень полезно. На мой взгляд, это должно быть в стандартных библиотеках C#, потому что преобразования очень распространены в каждой программе;)

BigChief 28.04.2013 20:52

Это очень приятно и полезно, НО я могу добавить, что это очень медленно, когда нужно делать преобразования для каждого элемента в большой коллекции элементов. Я протестировал 20000 элементов: при таком подходе преобразование 8 свойств каждого элемента занимает до 1 часа для завершения всей коллекции. С теми же образцами данных, но с использованием Подход Мэтта Гамильтона, это займет всего несколько секунд.

zed 07.04.2016 19:09

Это универсальное решение без накладных расходов на отражение.

public static Nullable<T> ParseNullable<T>(string s, Func<string, T> parser) where T : struct
{
    if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(s.Trim())) return null;
    else return parser(s);
}

static void Main(string[] args)
{
    Nullable<int> i = ParseNullable("-1", int.Parse);
    Nullable<float> dt = ParseNullable("3.14", float.Parse);
}

Думаю можно заменить IsNullOrEmpty на IsNullOrWhitespace

NibblyPig 21.07.2016 16:27

Я придумал этот, который удовлетворил мои требования (я хотел, чтобы мой метод расширения как можно ближе имитировал возврат TryParse фреймворка, но без блоков try {} catch {} и без жалоб компилятора на вывод тип, допускающий значение NULL, в рамках метода)

private static bool TryParseNullableInt(this string s, out int? result)
{
    int i;
    result = int.TryParse(s, out i) ? (int?)i : null;
    return result != null;
}

    public static void Main(string[] args)
    {

        var myString = "abc";

        int? myInt = ParseOnlyInt(myString);
        // null

        myString = "1234";

        myInt = ParseOnlyInt(myString);
        // 1234
    }
    private static int? ParseOnlyInt(string s)
    {
        return int.TryParse(s, out var i) ? i : (int?)null;
    }

если myString не является числовым, int.Parse генерирует исключение, что не то же самое, что возврат null.

an phu 18.03.2016 01:18

Предлагаю код ниже. Вы можете работать с исключением, когда произошла ошибка конвертации.

public static class Utils {      
public static bool TryParse<Tin, Tout>(this Tin obj, Func<Tin, Tout> onConvert, Action<Tout> onFill, Action<Exception> onError) {
  Tout value = default(Tout);
  bool ret = true;
  try {
    value = onConvert(obj);
  }
  catch (Exception exc) {
    onError(exc);
    ret = false;
  }
  if (ret)
    onFill(value);
  return ret;
}

public static bool TryParse(this string str, Action<int?> onFill, Action<Exception> onError) {
  return Utils.TryParse(str
    , s => string.IsNullOrEmpty(s) ? null : (int?)int.Parse(s)
    , onFill
    , onError);
}
public static bool TryParse(this string str, Action<int> onFill, Action<Exception> onError) {
  return Utils.TryParse(str
    , s => int.Parse(s)
    , onFill
    , onError);
}
}

Используйте этот метод расширения в коде (заполните свойство int? Age класса человека):

string ageStr = AgeTextBox.Text;
Utils.TryParse(ageStr, i => person.Age = i, exc => { MessageBox.Show(exc.Message); });

ИЛИ ЖЕ

AgeTextBox.Text.TryParse(i => person.Age = i, exc => { MessageBox.Show(exc.Message); });

Я бы предложил следующие методы расширения для синтаксического анализа строки в значение int с возможностью определения значения по умолчанию в случае, если синтаксический анализ невозможен:

public static int ParseInt(this string value, int defaultIntValue = 0)
        {
            return int.TryParse(value, out var parsedInt) ? parsedInt : defaultIntValue;
        }

public static int? ParseNullableInt(this string value)
        {
            if (string.IsNullOrEmpty(value))
                return null;

            return value.ParseInt();
        }

Уже есть так много ответов, и они получили даже много голосов. Вы действительно думаете, что ваш ответ нужен и придает новое качество этому посту?

L. Guthardt 12.03.2018 12:23

@ L.Guthardt Да, я так думаю. На мой взгляд, мой ответ предлагает более универсальный способ решения проблемы, описанной в вопросе. Спасибо.

Aleksandr Neizvestnyi 12.03.2018 12:53

C# <7.1

используя оператор по умолчанию

var result = int.TryParse(foo, out var f) ? f : default(int?);

C#> = 7.1

используя литерал по умолчанию

var result = int.TryParse(foo, out var f) ? f : default;

See C# language versioning to ascertain what language version your project supports

Редактировать:

См. Для справки снимок экрана ниже (C# Interactive):

Источники:

как это могло работать? Tryparse не будет работать или переменные, допускающие значение NULL, а f в вашем примере должно быть NULL.

John Lord 06.02.2020 20:53

Не могли бы вы прояснить, что вы имеете в виду @JohnLord

Jaa H 24.03.2020 18:51

tryparse ожидает, что он будет помещен в переменную, не допускающую значения NULL, поэтому разве ваше значение по умолчанию (int?) не заставит var иметь значение NULL?

John Lord 24.03.2020 19:17

TryParse возвращает bool, условный оператор используется для оценки результата, если true, присваивает вывод, иначе назначает тип по умолчанию, если вы используете Nullable.GetUnderlyingType, вы увидите, что это null.

Jaa H 10.03.2021 19:32

@JohnLord Я обновил свой ответ скриншотом из C# Interactive, надеюсь, это сделает его намного понятнее.

Jaa H 11.03.2021 12:42

Другие вопросы по теме