首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 加法運算完整指南:數值/列舉/字串/委派語意、溢位、IEEE 754 與運算子多載模式

     編輯:關於C#

加法運算 (+) 是 C# 最多型的運算子,支援數值加法、列舉位移、字串串接、委派合併與 TimeSpan 運算。各類型語意截然不同,且涉及溢位、精度、不可變性等關鍵特性。深入掌握這些細節,是正確建模領域邏輯與避免效能陷阱的基礎。

支援加法的類型總覽

類型分類形式語意結果類型關鍵特性
整數/浮點數/decimala + b數值加法較大類型溢位/精度/IEEE 754
列舉E + U, U + E基底值位移E不支援 E + E
字串s + s, s + obj串接string不可變、配置新物件
委派D + D合併調用清單D不可變、null 安全
TimeSpanTS + TS, DT + TS時間累加TimeSpan / DateTime溢位例外
指標 (unsafe)T* + n指標位移T*元素大小倍數

數值加法:溢位與 IEEE 754 特殊值

整數溢位

int max = int.MaxValue; // 2147483647

// unchecked (預設):環繞
var wrap = max + 1; // -2147483648 (MinValue)

// checked:拋出 OverflowException
checked { max + 1; } // Exception

// 長整數避免溢位
long safe = (long)max + 1; // 2147483648L

浮點數特殊值表

a + b結果說明
∞ + ∞∞同號無窮大相加
∞ + (-∞)NaN不定式
正常 + ∞∞吸收
+0.0 + -0.0+0.0正零優先
NaN + 任何NaN傳播

decimal 加法

decimal a = 0.1m, b = 0.2m;
decimal c = a + b; // 0.3m (精確,無二進位誤差)

// 範圍:±7.9e28,溢位拋出 OverflowException
decimal.MaxValue + 1; // OverflowException

列舉加法:基底值位移 (非旗標合併)

enum Weekday { Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6 }

// E + U → E (位移)
Weekday d = Weekday.Mon + 3; // Weekday.Thu (值 4)

// U + E → E (相同)
Weekday d2 = 3 + Weekday.Mon; // Weekday.Thu

// 底層機制:(E)((U)E + U) — 基底整數加法後轉回列舉
// 注意:結果可能無對應列舉成員 (如 Mon + 10 = 11)
// 旗標合併請用位元 OR:FlagsEnum.A | FlagsEnum.B

實戰範例:日期計算

enum Month { Jan=1, Feb=2, ..., Dec=12 }
Month m = Month.Jan;
m = m + 3; // Month.Apr (值 4)

// 循環位移需自行處理
Month NextMonth(Month m, int offset) 
    => (Month)((((int)m - 1 + offset) % 12) + 1);

字串串接:不可變性與效能

多載形式

string + string           → string
string + object           → string (呼叫 ToString())
object + string           → string (呼叫 ToString())
// 注意:object + object 無 + 多載 (編譯錯誤)

編譯器優化:單一陳述式內常數摺疊

// 編譯時期合併
string s = "Hello" + " " + "World"; // "Hello World" (單一字面常數)

// 執行期:每次 + 都配置新字串
string a = "A";
string b = "B";
string c = a + b; // 新配置 "AB"
string d = c + "C"; // 新配置 "ABC"

// 迴圈中災難性效能
string result = "";
for (int i = 0; i < 1000; i++) 
    result += i.ToString(); // 1000 次配置,O(n²)

// 正確:StringBuilder
var sb = new StringBuilder();
for (int i = 0; i < 1000; i++) 
    sb.Append(i);
string efficient = sb.ToString(); // 單次配置

// C# 10+:字串插值優化
string modern = $"{a}{b}{c}"; // 編譯為 StringBuilder 或 String.Concat

String.Concat vs StringBuilder

// 少量 (≤4) 字串:Concat 最佳
string s = String.Concat(a, b, c, d);

// 大量/動態:StringBuilder
var sb = new StringBuilder(capacity: 1000); // 預分配避免擴容

委派合併:不可變多播

語意規則

Action a1 = () => Console.WriteLine("A");
Action a2 = () => Console.WriteLine("B");

Action multi = a1 + a2; // 新委派,清單 [a1, a2]
// a1, a2 不變

// null 安全
Action nullAct = null;
Action combo = a1 + nullAct; // [a1]
combo = nullAct + a1;        // [a1]

// 相同委派可重複合併
Action dup = a1 + a1; // [a1, a1] — 執行兩次 A

事件訂閱語法糖

event Action OnEvent;

OnEvent += Handler; // 實為 OnEvent = OnEvent + Handler
OnEvent -= Handler; // 實為 OnEvent = OnEvent - Handler

TimeSpan/DateTime 加法

TimeSpan t1 = TimeSpan.FromHours(2);
TimeSpan t2 = TimeSpan.FromMinutes(30);
TimeSpan sum = t1 + t2; // 2.5 小時

DateTime now = DateTime.Now;
DateTime future = now + TimeSpan.FromDays(7); // 一週後

// DateTime + DateTime 不支援 (無語意)
// 溢位檢查
DateTime.MaxValue + TimeSpan.FromSeconds(1); // OverflowException

使用者定義型別多載標準模式

public readonly struct Vector3
{
    public double X, Y, Z;
    
    public static Vector3 operator +(Vector3 a, Vector3 b) 
        => new Vector3 { X = a.X + b.X, Y = a.Y + b.Y, Z = a.Z + b.Z };
    
    // 標量加法 (不常見,通常用乘法)
    public static Vector3 operator +(Vector3 v, double k) 
        => new Vector3 { X = v.X + k, Y = v.Y + k, Z = v.Z + k };
    
    // 交換律支援
    public static Vector3 operator +(double k, Vector3 v) => v + k;
}

效能特性對比

類型單次操作成本記憶體配置最佳實踐
整數/浮點數1-5 週期無 (暫存器)直接使用
decimal~50-100 週期無避免熱路徑
字串O(n) 配置+複製每次新字串StringBuilder / 插值
委派~微秒新陣列+委派物件快取合併結果
TimeSpan~10 週期無 (結構)直接使用

最佳實踐總結

  1. 整數加法溢位風險 — 用 checked、long 或 TryAdd (Core 2.0+)
  2. 浮點數 ∞ + (-∞) = NaN — 檢查特殊值避免污染
  3. 字串串接迴路必用 StringBuilder — 或 C# 10+ 插值語法
  4. 列舉加法僅支援 E+U — 旗標合併用 |,非 +
  5. 委派合併不可變 — 原委派不變,結果快取避免重複合併
  6. TimeSpan/DateTime 型別安全 — 編譯器防止無語意組合
  7. 自訂型別多載 + 遵循交換律/結合律 — 符合數學直覺

精通加法運算在各類型上的語意邊界與效能特性,能編寫正確、高效且符合領域直覺的程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved