Dlaczego pierwsza i druga funkcja Write działają, a nie ostatnia? Czy istnieje sposób, w jaki mogę zezwolić na wszystkie 3 z nich i wykryć, czy był to 1, (int) 1, czy też przeszedłem? I naprawdę, dlaczego jeden jest dozwolony, ale ostatni? Drugie pozwolenie, ale nie ostatnie, naprawdę zaskakuje mnie.
Demo pokazujące błąd kompilacji
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!?
}
}
c#
compiler-errors
int
type-conversion
implicit-conversion
CodesInChaos
źródło
źródło
(short) i
.Odpowiedzi:
Pierwsze dwa to wyrażenia stałe, a ostatnie nie.
Specyfikacja C # umożliwia niejawną konwersję z int do short dla stałych, ale nie dla innych wyrażeń. Jest to rozsądna zasada, ponieważ w przypadku stałych kompilator może zapewnić, że wartość pasuje do typu docelowego, ale nie może tego zrobić w przypadku zwykłych wyrażeń.
Zasada ta jest zgodna z wytyczną, zgodnie z którą niejawne konwersje powinny być bezstratne.
(Cytat z specyfikacji języka C # w wersji 3.0)
źródło
Ze względu na możliwość obcięcia nie ma niejawnej konwersji z
int
nashort
. Jednak wyrażenie stałe może być traktowane jako typ docelowy przez kompilator .1
? Nie ma problemu: to oczywiście ważnashort
wartość.i
? Nie tak bardzo -short.MaxValue
na przykład może to być jakaś wartość , a kompilator nie może tego sprawdzić w ogólnym przypadku.źródło
Expression<Func<int>>
? Następnie możesz przekazać() => 1
lub() => i
wewnątrz funkcji sprawdzić, czy przekazana jednostka zawiera przechwyconą zmienną lub stałą wartość.int
dosłownym można niejawnie przekształca sięshort
. Natomiast:Tak więc pierwsze dwa działają, ponieważ niejawna konwersja literałów jest dozwolona.
źródło
Uważam, że dzieje się tak, ponieważ w pierwszych dwóch podajesz literał / stałą, ale nie ma automatycznej konwersji typu podczas przekazywania liczby całkowitej w trzeciej.
Edycja: Ktoś mnie pokonał!
źródło
Ponieważ nie będzie żadnej niejawnej konwersji między Nonliteral typem o większym rozmiarze.
Niejawna konwersja jest możliwa tylko w przypadku wyrażenia stałego.
Gdzie jak przekazujesz
integer
wartość jako argument doshort
źródło
Kompilator powiedział ci, dlaczego kod nie działa:
Oto pytanie, które powinieneś zadać: dlaczego ta konwersja się nie udaje? Wyszukałem w Google „c # convert int short” i znalazłem się na stronie MS C # dla
short
słowa kluczowego:http://msdn.microsoft.com/en-us/library/ybs77ex4(v=vs.71).aspx
Jak mówi ta strona, niejawne rzutowania z większego typu danych na
short
są dozwolone tylko dla literałów. Kompilator może stwierdzić, kiedy literał jest poza zakresem, ale nie inaczej, więc potrzebuje zapewnienia, że uniknąłeś błędu poza zakresem w logice programu. To zapewnienie zapewnia obsada.źródło
Konwersja z int -> short może spowodować obcięcie danych. Dlatego.
źródło