web-dev-qa-db-ja.com

1をint変数iではなくshortとして渡すことができるのはなぜですか?

なぜ最初と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!?
    }
}
146
user34537

最初の2つは定数式で、最後の2つはそうではありません。

C#仕様では、定数を暗黙的にintからshortに変換できますが、他の式は変換できません。これは合理的なルールです。定数の場合、コンパイラは値がターゲットタイプに適合することを保証できるが、通常の式にはできないためです。

このルールは、暗黙的な変換はロスレスである必要があるというガイドラインに沿っています。

6.1.8暗黙的な定数式の変換

暗黙的な定数式の変換では、次の変換が許可されます。

  • タイプintconstant-expression(7.18)は、タイプsbytebyteshortushortuint、またはulongconstant-expressionの値が範囲内にある場合)宛先タイプの。
  • constant-expressionのタイプlongは、constant-の値があれば、タイプulongに変換できます。 expressionは負ではありません。

(C#言語仕様バージョン3.0から引用)

186
CodesInChaos

切り捨ての可能性があるため、intからshortへの暗黙的な変換はありません。ただし、定数式は、ターゲットタイプコンパイラーとして処理できます。

1?問題ではありません。明らかに有効なshort値です。 i?それほどではない-何らかの値である可能性がある> short.MaxValueたとえば、コンパイラは一般的なケースではそれをチェックできません。

67
Konrad Rudolph

intliteralは、暗黙的に short に変換できます。一方、

大きなストレージサイズの非リテラル数値型を暗黙的にshortに変換することはできません

したがって、リテラルの暗黙的な変換が許可されているため、最初の2つは機能します。

最初の2つでリテラル/定数を渡しているが、3つ目の整数を渡すときに自動型変換がないためだと思います。

編集:誰かがそれに私を打ち負かした!

6
Justin

Nonliteralタイプからより大きなサイズのshortへの変換暗黙が行われないためです。

暗黙的な変換は、constant-expressionでのみ可能です。

public static void Write(short v) { }

integerの値をshortの引数として渡す場合

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

コンパイラには、コードが失敗する理由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)
3

Int-> shortから変換すると、データが切り捨てられる場合があります。それが理由です。

0
ak1238