如何在 C# 中减去一行上的字节

发布于 2024-10-09 20:07:59 字数 641 浏览 6 评论 0原文

这确实很奇怪。谁能解释一下吗?

这段代码不起作用:

const byte ASC_OFFSET = 96;
string Upright = "firefly";
byte c7 = (byte)Upright[6] - ASC_OFFSET;
//Cannot implicitly convert type 'int' to 'byte'.

这段代码也不起作用:

const byte ASC_OFFSET = 96;
string Upright = "firefly";
byte c7 = (byte)Upright[6] - (byte)ASC_OFFSET;
//Cannot implicitly convert type 'int' to 'byte'.

然而,将减法放在单独的行上效果很好:

const byte ASC_OFFSET = 96;
string Upright = "firefly";
byte c7 = (byte)Upright[6];
c7 -= ASC_OFFSET;

如果必须的话,我不介意将语句放在单独的行上......但我想知道...

为什么?

This is really odd. Can anyone explain this?

This code does NOT work:

const byte ASC_OFFSET = 96;
string Upright = "firefly";
byte c7 = (byte)Upright[6] - ASC_OFFSET;
//Cannot implicitly convert type 'int' to 'byte'.

This code also does NOT work:

const byte ASC_OFFSET = 96;
string Upright = "firefly";
byte c7 = (byte)Upright[6] - (byte)ASC_OFFSET;
//Cannot implicitly convert type 'int' to 'byte'.

Yet, putting the subtraction on a separate line works just fine:

const byte ASC_OFFSET = 96;
string Upright = "firefly";
byte c7 = (byte)Upright[6];
c7 -= ASC_OFFSET;

I don't mind putting the statements on separate lines, if I have to... but I have to wonder...

Why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

够运 2024-10-16 20:07:59

这是因为 1) byte 运算结果为 int (请参阅此处的原因:http://blogs.msdn.com/b/oldnewthing/archive/2004/03/10/87247.aspx)和2)以下 C# 代码

c7 -= ASC_OFFSET;

将在后台“神奇地”编译为

c7 = (byte)(c7 - ASC_OFFSET);

C# 规范中明确记录的内容: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf

14.14.2 复合赋值:

x op= y 形式的运算是
通过应用二元运算符进行处理
重载解析(§14.2.4)就像
该操作被写为 x op y。
那么,

• 如果返回类型
选择的运算符是隐式的
可转换为 x 的类型,
操作计算为 x = x op y,
只不过 x 只计算一次。

否则,如果所选运算符是预定义运算符,且所选运算符的返回类型可显式转换为 x 的类型,且 y 可隐式转换为 x 的类型,或者运算符为移位运算符,则该运算的计算结果为 x = (T)(x op y),其中 T 是 x 的类型,但 x 仅计算一次。


否则,复合赋值是
无效,并且出现编译时错误
发生

This is because 1) byte operations result in int (see why here: http://blogs.msdn.com/b/oldnewthing/archive/2004/03/10/87247.aspx) and 2) the following C# code

c7 -= ASC_OFFSET;

will be "magically" compiled behind the scene into

c7 = (byte)(c7 - ASC_OFFSET);

This is explicitely documented in C# specification here: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf

14.14.2 Compound assignment:

An operation of the form x op= y is
processed by applying binary operator
overload resolution (§14.2.4) as if
the operation was written x op y.
Then,

• If the return type of the
selected operator is implicitly
convertible to the type of x, the
operation is evaluated as x = x op y,
except that x is evaluated only once.

Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x or the operator is a shift operator, then the operation is evaluated as x = (T)(x op y), where T is the type of x, except that x is evaluated only once.


Otherwise, the compound assignment is
invalid, and a compile-time error
occurs

别低头,皇冠会掉 2024-10-16 20:07:59

前两个示例无法编译的原因是:

  • 强制转换比减法绑定“更紧密”。也就是说,“(C)de”表示“((C)d)-e”,而不是“(C)(de)”。强制转换运算符的优先级更高。
  • 因此,无论进行何种类型转换,减法的两个操作数的类型都是字节。
  • 减法的类型是 int,因为没有在字节上定义减法运算符。
  • 因此,您将 int 分配给字节而不进行强制转换,这是非法的。

字节上没有减法运算符,因为假设您有一个包含 7 的字节,并从中减去一个包含 8 的字节,您真的希望它成为字节 255 吗?我想大多数人会希望它是 int -1。

最后,你到底为什么要以字节为单位这样做?这没有任何意义。 C# 中的字符不是字节;如果你想对字符进行算术,那么为什么不从字符'y'中减去char 96,而不是进行有损且危险的字节转换?

The reason why your first two samples do not compile is because:

  • The cast binds "tighter" than the subtraction. That is, '(C)d-e' means '((C)d)-e', not '(C)(d-e)'. The cast operator is higher precedence.
  • Therefore the type of both operands to the subtraction is byte, regardless of the casts.
  • The type of the subtraction is int, because there is no subtraction operator defined on bytes.
  • Therefore, you are assigning an int to a byte without a cast, which is illegal.

There is no subtraction operator on bytes because, well, suppose you have a byte containing 7 and you subtract from it a byte containing 8, do you really want that to be the byte 255? I think most people would want that to be the int -1.

Finally, why on earth are you doing this in bytes in the first place? This doesn't make any sense. Chars aren't bytes in C#; if you want to do arithmetic on chars then why not subtract the char 96 from the char 'y' instead of doing a lossy and dangerous conversion to byte?

你曾走过我的故事 2024-10-16 20:07:59

我以前也注意到过这一点。我认为这是因为 -= 运算符是为字节类型预定义的,而在前一种情况下,您实际上是将 int 放入 byte 中>,这是不允许的。他们这样做的原因不一定有意义,但它符合规则,因为在前一种情况下,编译器在进行赋值时无法“查看”- 运算符。

如果您确实需要在一行上进行减法,请不要说: 而是

byte c7 = (byte)Upright[6] - ASC_OFFSET;

说:

byte c7 = (byte)(Upright[6] - ASC_OFFSET);

I've noticed this before too. I think it's because the -= operator is predefined for byte types, whereas in the former cases, you're really putting an int inside a byte, which isn't allowed. The reason they did this doesn't necessarily make sense, but it's consistent with the rules, because in the former cases, the compiler can't "peek" at the - operator when doing the assignment.

If you really need to subtract on one line, instead of saying:

byte c7 = (byte)Upright[6] - ASC_OFFSET;

Say:

byte c7 = (byte)(Upright[6] - ASC_OFFSET);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文