【问题标题】:C# does not let me sum two shorts to a short [duplicate]C#不允许我将两条短裤相加为一个短裤[重复]
【发布时间】:2012-08-04 22:02:58
【问题描述】:

我有一个代码:

static short Sum(short a, short b)
        {
            return a + b;
        }

而且它不能编译,saynig 不能将 'int' 转换为 'short'。我今天可能真的很累,但我看不到问题!

【问题讨论】:

标签: c# type-conversion


【解决方案1】:

而且它不能编译,saynig 不能将 'int' 转换为 'short'。我今天可能真的很累,但我看不到问题!

这就是语言的定义方式。整数类型的 + 运算符定义为:

static uint op +(uint x, uint y)
static int op +(int x, int y)
static ulong op +(ulong x, ulong y)
static long op +(long x, long y)

根据需要提升操作数。

现在至于 原因 为何如此定义 - 老实说,我不知道。我不赞成“因为它可能溢出”的论点——这表明应该将byte + byte 定义为返回short,而int + int 应该返回long,这两者都不是真的。

我在某处听说这可能与性能有关,但我不想肯定地说。 (也许处理器通常只提供对 32 位和 64 位整数的整数运算?)

不管怎样,这并不真正重要为什么会这样 - 这只是语言的规则。

请注意,复合赋值运算符有一个隐式转换回相关类型,所以你可以这样写:

short x = 10;
short y = 20;
x += y;

【讨论】:

  • 谢谢,所以即使我想使用尽可能少的内存,我只需要在这里使用整数?
  • @user970696:不,你可以投:return (short) a + b;。但我会警惕微优化......
  • @JonSkeet 那也不会编译(操作顺序)。您需要用括号括起来。
  • 乔恩-为我辩护:stackoverflow.com/a/4347752/1583
  • @Oded:很公平,但在这种情况下,它仍然感觉像是一个弱论点即使这意味着不同意 Eric。我去拿我的外套。
【解决方案2】:

当您将两个短裤相加时,它们的总和可能超过一个短裤的允许值,但对于 int 来说是一个 OK 值。这几乎就是 Eric Lippert 在his answer here 中所说的。


旁白:为什么添加两个 ints 返回一个 long 不是这种情况? Eric 也提到了这一点:

在一个整数算术环绕它的世界中,在 int 中进行所有计算更为明智,这种类型可能有足够的范围使典型计算不会溢出。


因此,在添加两个 shorts 时定义的 + 运算符返回一个 int

这就是您收到编译时错误的原因 - 您正在返回一个 int,而您在其中指定了一个 short 返回类型`。

如果您知道添加将总是导致short,则可以将结果显式转换为short

static short Sum(short a, short b)
{
    return (short)(a + b);
}

【讨论】:

  • 这是一个不让你将两个 int 值相加得到另一个 int 的论据。
  • 是的,他们可以,但不是必须的。我可以用整数做到这一点并期待很长的时间..
  • @JonSkeet 啊,但发生这种情况的可能性只有一半。
  • @user970696:你可以期待它,但你会失望的。如果您添加int.MaxValue1,您将不会得到大于int.MaxValuelong 值 - 您将得到int.MinValue
  • @user970696 - 没错,但不是语言的工作原理。设计师决定允许ints 溢出,但不允许shorts。
【解决方案3】:

Jon Skeet 有explained in detail 为什么你的代码不能工作,但他没有列出你需要做什么才能编译它。您可以使用以下内容:

static short Sum(short a, short b)
{
    return (short)(a + b);
}

【讨论】:

  • 没关系,我正在寻找一种方法来简单地导致溢出异常;)
  • 您应该考虑short x + short y 超过空头最大值的情况;让它抛出异常。 @user970696 导致溢出异常的最简单方法就是 throw new OverflowException();
  • @aevitas 这取决于是否需要抛出异常。无论哪种情况,您都应该在代码周围使用checkedunchecked 块来获得所需的行为,而不是手动检查并抛出异常。
  • 嗯,我正在寻找如何让 C# 自然地导致该异常,而不强制它使用内置机制。
  • 是的,return checked((short)(x + y));
猜你喜欢
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多