Neden 1'i kısa olarak geçebiliyorum ama int değişkeni i'yi geçemiyorum?


146

Neden birinci ve ikinci Yazma çalışıyor ama sonuncusu çalışmıyor? Bunların 3'üne de izin verip 1 mi, (int) 1 mi yoksa ben mi geçtiğimi tespit etmenin bir yolu var mı? Ve gerçekten neden sonuncusuna izin verilir? İkincisine izin verilir ama sonuncusu gerçekten aklımı başımdan alır.

Derleme hatasını gösterme demosu

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!?
    }
}

2
Onlar ... dökülebilir olmalıdır rağmen ben de bu kelimler am i genellikle fonksiyon çağrıları kısa üzere döküm ints zorunda
Mathieu Dumoulin

2
@MathieuDumoulin castlenebilirler, bu yüzden onları cast edebilirsiniz. Ama bu kayıplı bir dönüşümdür (kısaca uymayan pek çok tamlık vardır), bu yüzden örtük atama mümkün değildir, bu yüzden yazmak zorundasınız (short) i.
Abel

Yanıtlar:


186

İlk ikisi sabit ifadelerdir, sonuncusu değildir.

C # belirtimi, sabitler için int'ten kısaya örtük bir dönüştürmeye izin verir, ancak diğer ifadeler için geçerli değildir. Bu makul bir kuraldır, çünkü sabitler için derleyici değerin hedef türe uymasını sağlayabilir, ancak normal ifadeler için yapamaz.

Bu kural, örtük dönüşümlerin kayıpsız olması gerektiği yönündeki yönergeye uygundur.

6.1.8 Örtük sabit ifade dönüşümleri

Örtük bir sabit ifade dönüşümü aşağıdaki dönüşümlere izin verir:

  • Bir sabit ekspresyon Çeşidi (§7.18) inttip dönüştürülebilir sbyte, byte, short, ushort, uint, ya da ulong, arasında bir değer sabit ekspresyon hedef türü aralığındadır.
  • Bir sabit ekspresyon Çeşidi longtipi dönüştürülebilir ulongdeğeri verilmedi, sabit ekspresyon negatif değildir.

(C # Dil Belirtimi Sürüm 3.0'dan alıntılanmıştır)


67

Örtük dönüştürme yoktur intiçin shortçünkü kesilmesi olasılığı. Bununla birlikte, sabit bir ifade , derleyici tarafından hedef tür olarak değerlendirilebilir .

1? Sorun değil: açıkça geçerli bir shortdeğer. i? Çok fazla değil - short.MaxValueörneğin bir değer olabilir ve derleyici genel durumda bunu kontrol edemez.


Yani ... ne kadar açık olduğum önemli değil ...> _ <. Bir litereal veya int değişkeninin geçip geçmediğini tespit edip edemeyeceğime dair bir fikriniz var mı?

@ acidzombie24 Yapamazsınız. Ama bunu neden yapmak isteyesiniz?
Adam Houldsworth

@ acidzombie24 Bunu tespit edebileceğini sanmıyorum. Sen olabilir ancak türünün ulaşmak için yansıma kullanmak sonra şablon argüman kullanmak ve.
Konrad Rudolph

3
@ acidzombie24 Çalışma zamanı sırasında değişmez bir bilginin aktarılmasının hiçbir yolu yoktur. Böylece derleme zamanında kontrol etmek için gözlerinizi kullanabilirsiniz.
Justin

1
@ acidzombie24 Bu durumda, argümanı bir olarak kabul etmek bir seçenek olur Expression<Func<int>>muydu? Ardından, geçebilir () => 1veya () => iişlevin içinde, geçirilen varlığın yakalanmış bir değişken veya sabit bir değer içerip içermediğini inceleyebilirsiniz.
Konrad Rudolph

8

bir int literal örtük olarak dönüştürülebilir short. Buna karşılık:

Sen örtük daha büyük depolama boyutunun mecazi sayısal türlerini dönüştürmek olamaz kısa

Bu nedenle, ilk ikisi çalışır çünkü değişmez değerlerin örtük dönüşümüne izin verilir.


3
Cevabınız biraz yanlış. Sen kullanmamalısınız değişmez ama sabit ifadesini . Özellikle, ikinci örnek, bir değil, değişmez .
CodesInChaos

6

Sanırım ilk ikisinde bir değişmez / sabit geçtiğiniz için, ancak üçüncü tamsayıya geçerken otomatik tür dönüşümü yok.

Düzenleme: Biri beni yendi!


3

Çünkü Nonliteral tür arasında daha büyük boyutlu kısaya herhangi bir örtük dönüşüm olmayacak .

Örtük dönüştürme yalnızca sabit ifade için mümkündür.

public static void Write(short v) { }

integerBir argüman olarak değeri nereye iletiyorsunuz?short

int i=1;
Write(i);  //Which is Nonliteral here

3

Derleyici size kodun neden başarısız olduğunu söyledi :

cannot convert `int' expression to type `short'

İşte sormanız gereken soru şu: bu dönüşüm neden başarısız oluyor? Google'da "c # convert int short" yazdım ve shortanahtar kelime için MS C # sayfasına geldim :

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

Bu sayfanın dediği gibi, daha büyük bir veri türünden örtük yayınlara shortyalnızca değişmez değerler için izin verilir. Derleyici, bir değişmez değerin aralık dışı olduğunu söyleyebilir, ancak başka türlü olamaz, bu nedenle program mantığınızda aralık dışı bir hatayı önlediğinizden emin olmanız gerekir. Bu güvence bir oyuncu kadrosu tarafından sağlanır.

Write((short)i)

0

İnt -> short biçiminden dönüştürme, verilerin kesilmesine neden olabilir. Bu yüzden.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.