В чём разница между Convert.ToString, ToString и (String)?

254
09 января 2018, 11:41

Например есть некая переменная:

int temp = 5;

Затем:

String a = Convert.ToString(temp);
String b = (temp).ToString();
String c = (String)temp;

В чём разница между этими выражениями?

Answer 1

Функция ToString() (вы забыли скобки) — это не приведение типов, это просто функция, которая для числа даёт его строковое представление.

Функция Convert.ToString(int) — это тоже не приведение типов, а функция, которая для числа даёт его строковое представление.

Обе функции ToString() и Convert.ToString() выдают строковое представление в текущей локали, так что различий быть не должно.

Приведение типов в ваших примерах лишь одно:

String c = (String)temp;

Это приведение типов не будет работать, т. к. temp имеет реальный тип int, а не string. Это даже не скомпилируется, т. к. компилятор видит, что число типа int никаким образом не может быть строкой. Приведение типов не меняет сам объект, оно просто меняет тип ссылки на настоящий тип объекта или какой-то из его базовых типов. (Вы ведь понимаете, что число 123 — это совсем не то же самое, что строка из трёх символов '1', '2' и '3'?)

Уголок зануды пуриста.

Вызовы 5.ToString() и Convert.ToString(5), согласно sourceof.net, являются вызовами

Number.FormatInt32(5, null, NumberFormatInfo.GetInstance(Thread.CurrentThread.CurrentCulture))

и

Number.FormatInt32(i, null, NumberFormatInfo.CurrentInfo)

внутреннего класса Number соответственно. Могут ли NumberFormatInfo.GetInstance(Thread.CurrentThread.CurrentCulture) и NumberFormatInfo.CurrentInfo не совпадать?

Код NumberFormatInfo.GetInstance для нашего случая можно упростить до следующего:

if (!cultureInfo.m_isInherited)
    return cultureInfo.numInfo ?? cultureInfo.NumberFormat;
return cultureInfo.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo ?? CurrentInfo;

А код NumberFormatInfo.CurrentInfo — до

CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
if (!cultureInfo.m_isInherited && cultureInfo.numInfo != null)
    return cultureInfo.numInfo;
return ((NumberFormatInfo)cultureInfo.GetFormat(typeof(NumberFormatInfo)));

В случае, когда cultureInfo.m_isInherited == false (то есть, у нас CultureInfo, а не производный от него тип), у нас cultureInfo.GetFormat(typeof(NumberFormatInfo)) возвращает NumberFormat, так что различий нет.

В случае же, когда у нас не CultureInfo, а производный от него тип, у нас код упрощается до

cultureInfo.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo ?? CurrentInfo;

и

((NumberFormatInfo)cultureInfo.GetFormat(typeof(NumberFormatInfo)));

Разный результат может быть лишь в случае, если переопределённая виртуальная функция GetFormat сошла с ума, и возвращает разные типы при разных вызовах.

class WeirdCultureInfo : CultureInfo
{
    public WeirdCultureInfo() : base("en-US") { }
    bool flag = false;
    public override object GetFormat(Type formatType)
    {
        object result = flag ? (object)DateTimeFormat : NumberFormat;
        flag = true;
        return result;
    }
}
READ ALSO
Необработанное исключение System.Reflection.TargetInvocationException и BackgroundWorker

Необработанное исключение System.Reflection.TargetInvocationException и BackgroundWorker

Изучаю BackgroundWorker, решил попробовать на своей программе (при проверке обновлений), добавив BackgroundWorkerВроде сделал всё примерно как на msdn, но программа...

211
С# Есть ли действительно удобный способ парсинга html?

С# Есть ли действительно удобный способ парсинга html?

Почему все способы парсинга html на с# такие сложные и запарные? Очень долго программировал на ahk, и там можно в одну строку запарсить classname просто...

285
Не доверять File.Exists() и использовать try/catch?

Не доверять File.Exists() и использовать try/catch?

На одной из страниц форума https://stackoverflowcom/a/6186400/2948684, где идет обсуждение if/else vs

219
Проверка TextBox'ов на пустоту

Проверка TextBox'ов на пустоту

Использую для проверки на пустоту такой способ

239