2010-07-21 41 views
5

考慮這種靜態的測試類:爲什麼C#在嘗試對int以外的整數類型進行數學運算時拋出轉換錯誤?

public static class Test 
{ 
    public static ushort sum(ushort value1, ushort value2) 
    { 
     return value1 + value2 
    } 
} 

這將導致以下編譯錯誤,與value1 + value2紅色下劃線:

無法隱式轉換類型「詮釋」 爲「USHORT」。存在明確的轉換 (您是否缺少演員表)?

爲什麼?

+0

編譯器要求您清楚表明您正在進行縮小轉換,其中數據可能會丟失。如果你通過ushort.MaxValue和1,會發生什麼?這是編譯器提醒你回答的問題。 – 2010-07-21 18:04:01

+0

@Dan:應該發生什麼是'ushort'應該自動溢出,或者在正在使用'checked'關鍵字時拋出溢出異常。如果添加兩個「int」值,即使可能發生溢出,也不會得到相同的編譯器錯誤。 – 2010-07-21 18:56:22

+0

我的看法:溢出是由於操作而發生的事情,而不是分配。尤其是,即使最終結果在範圍內,您也可以在複雜計算中溢出。如果發生溢出,數學運算無法按預期運行,但在32位系統上添加兩個ushort時不會發生這種情況。數學運作良好,但你現在必須決定如何解釋結果。如果你想讓它溢出,那麼你可以明確地將它轉換爲ushort。這可能會隱式發生,但要求進行明確的轉換會很有幫助。 – 2010-07-21 19:38:46

回答

7

與之前的C和C++類似,整數在與許多運算符一起使用時會隱含地加寬。在這種情況下,將兩個ushort值加在一起的結果是int

更新:

的更多信息:http://msdn.microsoft.com/en-us/library/aa691330(v=VS.71).aspx

我相信這在C最初添加/ C++,因爲int是一個原生的整數類型(是的,操作比short是快上int小號s在32位體系結構上)。我不確定C#的全部基本原理。

當您投射時,它會讓您考慮溢出/截斷的考慮因素。對於較小的整數類型,意外溢出更可能。

+0

所以這樣做是因爲它總是這樣做? – 2010-07-21 17:45:21

+0

因爲無論如何都必須存在轉換,所以轉換爲單一類型並應用運算符比在已存在的轉換之上爲每個類型單獨實現運算符要容易。 – murgatroid99 2010-07-21 17:47:47

+2

那,並且機器隱式地算術爲'int'。另外,如果有很多隱式轉換,編譯器將更有可能選擇一個你並不想要的轉換。 (例如參見PL/I)。 – 2010-07-21 17:47:52

5

ushort

下面的賦值語句因爲 算術表達式賦值運算符 的右側評估默認爲int 會產生一個編譯錯誤, 。

ushort z = x + y; // Error: conversion from int to ushort 

要解決此問題,使用強制:

ushort z = (ushort)(x + y); // OK: explicit conversion 
2

在C#中可用的加法運算符只考慮intuintlongulong數據類型,所以在這種情況下,您隱式將兩個ushort實例投射到int,然後執行加法和th返回int,不能隱式轉換爲ushort

從C#4.0規範中,部分7.8。4加法運算符,可以檢查,只有以下的整數加法運算符:

int operator +(int x, int y); 
uint operator +(uint x, uint y); 
long operator +(long x, long y); 
ulong operator +(ulong x, ulong y); 

相同的部分也規定:

操作數被轉換爲 參數類型所選擇的 運算符,結果類型 是運算符的返回類型。

這解釋了爲什麼該表達式產生int

1

這是因爲增加或減少ushorts並不一定會導致ushort。例如,結果可能是< 0,這不是一個ushort。所以你需要給編譯器提示不要通過輸入類型來投訴它。我相信這應該工作:return(ushort)(value1 + value2);

相關問題