Why can I pass 1 as a short, but not the int varia

2019-01-16 07:07发布

Why does the first and second Write work but not the last? Is there a way I can allow all 3 of them and detect if it was 1, (int)1 or i passed in? And really why is one allowed but the last? The second being allowed but not the last really blows my mind.

Demo to show compile error

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

7条回答
等我变得足够好
2楼-- · 2019-01-16 07:23

I believe it is because you are passing in a literal/constant in the first two, but there is not automatic type conversion when passing in an integer in the third.

Edit: Someone beat me to it!

查看更多
\"骚年 ilove
3楼-- · 2019-01-16 07:29

an int literal can be implicitly converted to short. Whereas:

You cannot implicitly convert nonliteral numeric types of larger storage size to short

So, the first two work because the implicit conversion of literals is allowed.

查看更多
唯我独甜
4楼-- · 2019-01-16 07:29

Converting from int -> short might result in data truncation. Thats why.

查看更多
太酷不给撩
5楼-- · 2019-01-16 07:33

The first two are constant expressions, the last one isn't.

The C# specification allows an implicit conversion from int to short for constants, but not for other expressions. This is a reasonable rule, since for constants the compiler can ensure that the value fits into the target type, but it can't for normal expressions.

This rule is in line with the guideline that implicit conversions should be lossless.

6.1.8 Implicit constant expression conversions

An implicit constant expression conversion permits the following conversions:

  • A constant-expression (§7.18) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.
  • A constant-expression of type long can be converted to type ulong, provided the value of the constant-expression is not negative.

(Quoted from C# Language Specification Version 3.0)

查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-01-16 07:38

The compiler has told you why the code fails:

cannot convert `int' expression to type `short'

So here's the question you should be asking: why does this conversion fail? I googled "c# convert int short" and ended up on the MS C# page for the short keyword:

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

As this page says, implicit casts from a bigger data type to short are only allowed for literals. The compiler can tell when a literal is out of range, but not otherwise, so it needs reassurance that you've avoided an out-of-range error in your program logic. That reassurance is provided by a cast.

Write((short)i)
查看更多
别忘想泡老子
7楼-- · 2019-01-16 07:41

Because there will not be any implicit conversion between Nonliteral type to larger sized short.

Implicit conversion is only possible for constant-expression.

public static void Write(short v) { }

Where as you are passing integer value as an argument to short

int i=1;
Write(i);  //Which is Nonliteral here
查看更多
登录 后发表回答