Почему я могу передать 1 как короткую, но не переменную int i?

Почему первая и вторая записи работают, но не последние? Есть ли способ, которым я могу разрешить все 3 из них и определить, было ли это 1, (int) 1 или я прошел? И действительно, почему разрешено, но последнее? Вторая возможность, но не последняя, ​​действительно ударит меня.

Демоверсия для компиляции

using System;
class Program
{
    public static void Write(short v) { }
    static void Main(string[] args)
    {
        Write(1);//ok
        Write((int)1);//ok
        int i=1;
        Write(i);//error!?
    }
}
+146
источник поделиться
7 ответов

Первые два являются постоянными выражениями, последний - нет.

Спецификация С# допускает неявное преобразование из int в short для констант, но не для других выражений. Это разумное правило, поскольку для констант компилятор может гарантировать, что значение вписывается в целевой тип, но не может для нормальных выражений.

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

6.1.8. Неявные преобразования константных выражений

Неявное преобразование константных выражений допускает следующие преобразования:

  • Константное выражение (§7.18) типа int может быть преобразовано в тип sbyte, byte, short, ushort, uint или ulong, если значение константное выражение находится в пределах диапазона типа назначения.
  • Константное выражение типа long может быть преобразовано в тип ulong, если значение константного выражения не является отрицательным.

(Цитируется по языковой версии С# версии 3.0)

+184
источник

Нет никакого неявного преобразования от int до short из-за возможности усечения. Однако константное выражение может быть обработано компилятором как целевой тип.

1? Не проблема: это явно действительное значение short. i? Не так много - например, может быть какое-то значение > short.MaxValue, и компилятор не может проверить это в общем случае.

+67
источник

an int литерал может быть неявно преобразован в short. Принимая во внимание:

Вы не можете неявно конвертировать нелитературные числовые типы большего размера хранилища в короткий

Итак, первые две работают потому, что допускается неявное преобразование литералов.

+8
источник

Я считаю, что это потому, что вы передаете литерал/константу в первых двух, но нет автоматического преобразования типов при передаче в целое число в третьем.

Изменить: Кто-то избил меня до этого!

+6
источник

Потому что не будет никакого неявного преобразования между типом Nonliteral и short size.

Неявное преобразование возможно только для константного выражения.

public static void Write(short v) { }

Если вы передаете значение integer в качестве аргумента short

int i=1;
Write(i);  //Which is Nonliteral here
+3
источник

Компилятор сказал вам, почему код не работает:

cannot convert `int' expression to type `short'

Итак, вот вопрос, на который вы должны спросить: почему это преобразование терпит неудачу? Я googled "С# convert int short" и попал на страницу MS С# для ключевого слова short:

http://msdn.microsoft.com/en-us/library/ybs77ex4(v=vs.71).aspx

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

Write((short)i)
+3
источник

Преобразование из int → short может привести к усечению данных. Вот почему.

0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос