なぜ最初と2番目の書き込みは機能するのに最後の書き込みは機能しないのですか? 3つすべてを許可し、それが1(int)1であったか、または渡されたかを検出する方法はありますか?そして本当に最後のものが許可されているのはなぜですか? 2番目の許可は許可されますが、最後の許可は本当に気になりません。
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つは定数式で、最後の2つはそうではありません。
C#仕様では、定数を暗黙的にintからshortに変換できますが、他の式は変換できません。これは合理的なルールです。定数の場合、コンパイラは値がターゲットタイプに適合することを保証できるが、通常の式にはできないためです。
このルールは、暗黙的な変換はロスレスである必要があるというガイドラインに沿っています。
6.1.8暗黙的な定数式の変換
暗黙的な定数式の変換では、次の変換が許可されます。
- タイプ
int
のconstant-expression(7.18)は、タイプsbyte
、byte
、short
、ushort
、uint
、またはulong
(constant-expressionの値が範囲内にある場合)宛先タイプの。- constant-expressionのタイプ
long
は、constant-の値があれば、タイプulong
に変換できます。 expressionは負ではありません。
(C#言語仕様バージョン3.0から引用)
切り捨ての可能性があるため、int
からshort
への暗黙的な変換はありません。ただし、定数式は、ターゲットタイプコンパイラーとして処理できます。
1
?問題ではありません。明らかに有効なshort
値です。 i
?それほどではない-何らかの値である可能性がある> short.MaxValue
たとえば、コンパイラは一般的なケースではそれをチェックできません。
int
literalは、暗黙的に short
に変換できます。一方、
大きなストレージサイズの非リテラル数値型を暗黙的にshortに変換することはできません
したがって、リテラルの暗黙的な変換が許可されているため、最初の2つは機能します。
最初の2つでリテラル/定数を渡しているが、3つ目の整数を渡すときに自動型変換がないためだと思います。
編集:誰かがそれに私を打ち負かした!
Nonliteralタイプからより大きなサイズのshortへの変換暗黙が行われないためです。
暗黙的な変換は、constant-expressionでのみ可能です。
public static void Write(short v) { }
integer
の値をshort
の引数として渡す場合
int i=1;
Write(i); //Which is Nonliteral here
コンパイラには、コードが失敗する理由toldがあります。
cannot convert `int' expression to type `short'
それで、あなたが尋ねるべき質問があります:この変換が失敗するのはなぜですか? 「c#convert int short」とグーグル検索し、MS C#ページでshort
キーワードを探しました:
http://msdn.Microsoft.com/en-us/library/ybs77ex4(v = vs.71).aspx
このページにあるように、より大きなデータ型からshort
への暗黙的なキャストはリテラルでのみ許可されています。コンパイラーはリテラルが範囲外にあることを知ることができますが、そうでない場合はそうではないため、プログラムロジックの範囲外エラーを回避したことを保証する必要があります。その安心はキャストによって提供されます。
Write((short)i)
Int-> shortから変換すると、データが切り捨てられる場合があります。それが理由です。