目錄
一、什么是拓展方法?
二、拓展方法有啥用?怎么寫拓展方法?
1. ?核心用途
2. ?編寫步驟
實現步驟
關鍵點說明
關鍵規則
3. ?注意事項
三、什么是運算符重載?
四、運算符重載有啥用?怎么寫?
1. ?核心用途
2. ?編寫步驟
3. ?可重載的運算符
4. ?注意事項
五、總結
?對比表:拓展方法 vs 運算符重載
前言:當代碼學會“七十二變”?
????????有沒有想過,讓?
string
?類型突然學會統計單詞數?或者讓你的自定義類像?int
?一樣支持加減乘除?????????C#的拓展方法就像“魔法外掛”,能讓任何類型瞬間解鎖新技能,而運算符重載則是“對象變身術”,讓你的類搖身一變成為數學高手!
本文將揭秘這兩個神器的使用秘籍,讓你告別冗長代碼,擁抱優雅語法——從此,你的代碼不僅能“說話”,還能“算卦”!
一、什么是拓展方法?
????????拓展方法(Extension Methods)?是C#中一種特殊的語法,允許為現有類型(包括密封類或系統類型)添加新方法,而無需修改原始代碼或創建子類。
概念
為現有的 非靜態變量 添加 新方法
作用
1.提高程序拓展性
2.不需要在對象中重新寫方法
3.不需要繼承來添加方法
4.為別人封裝的類型寫額外的方法
特點
1.一定是寫在靜態類中
2.一定是個靜態函數
3.第一個參數為拓展目標
4.第一個參數用this修飾
- ?核心特點:
- 定義在靜態類中,方法為靜態方法。
- 第一個參數用?
this
?關鍵字修飾,表示要擴展的類型。 - ?擴展方法的本質是一個靜態方法,但在調用時,編譯器會自動將實例對象(即調用者)?作為第一個參數傳遞進去。這種語法糖讓擴展方法看起來像是實例方法,但實際上背后是靜態方法的調用邏輯。
基本語法:訪問修飾符 static 返回值 函數名(this 拓展類名 參數名,參數類型 參數名,)
- ?示例:為?
string
?類型添加一個統計單詞數的方法。
public static class StringExtensions {public static int WordCount(this string str) {return str.Split(new[] {' ', '.', '?'}, StringSplitOptions.RemoveEmptyEntries).Length;}
}// 使用
string text = "Hello, how are you?";
Console.WriteLine(text.WordCount()); // 輸出 4
二、拓展方法有啥用?怎么寫拓展方法?
1. ?核心用途
- ?擴展現有類型功能:尤其適用于無法修改源碼的類(如系統類型或第三方庫)。
- ?鏈式調用:讓代碼更流暢(如LINQ基于拓展方法實現)。
var numbers = new List<int> { 1, 2, 3 };
var sum = numbers.Where(n => n > 1).Sum(); // LINQ的Where和Sum均為拓展方法
2. ?編寫步驟
- ?創建靜態類:類名建議以?
Extensions
?結尾(如?StringExtensions
)。 - ?定義靜態方法:第一個參數用?
this
?修飾,表示目標類型。
基本語法:訪問修飾符 static 返回值 函數名(this 拓展類名 參數名,參數類型 參數名,)
public static class MathExtensions {public static double Square(this int num) => num * num;
}
// 使用
int num = 5;
Console.WriteLine(num.Square()); // 25
????????除了為系統內部的類型進行拓展方法,我們自己還可以為自己寫的靜態類進行拓展方法:??????假設有一個?Product
?類,表示商品信息:
實現步驟
- ?定義靜態類:創建名為?
ProductExtensions
?的靜態類。 - ?編寫擴展方法:添加一個靜態方法,第一個參數用?
this Product product
?修飾。 - ?實現邏輯:在方法內部訪問?
Product
?的公開屬性。
public class Product {public string Name { get; set; }public decimal Price { get; set; }public int Stock { get; set; }
}
????????我們希望為?Product
?添加一個擴展方法,用于生成商品描述的格式化字符串,而無需修改?Product
?類的原始代碼。就可以如下書寫:
public static class ProductExtensions {// 擴展方法:生成商品描述public static string GetDescription(this Product product) {return $"{product.Name} - 價格:¥{product.Price},庫存:{product.Stock}件";}// 擴展方法:檢查庫存是否充足public static bool IsInStock(this Product product, int requiredQuantity) {return product.Stock >= requiredQuantity;}
}
測試:
// 創建商品實例
var product = new Product {Name = "無線藍牙耳機",Price = 299.99m,Stock = 50
};// 調用擴展方法
string description = product.GetDescription();
bool isAvailable = product.IsInStock(30);Console.WriteLine(description);
// 輸出:無線藍牙耳機 - 價格:¥299.99,庫存:50件
Console.WriteLine(isAvailable ? "庫存充足" : "庫存不足");
// 輸出:庫存充足
關鍵點說明
?靜態類與靜態方法:
- 所有擴展方法必須定義在?
static class
?中。- 方法本身必須是?
static
?的,且第一個參數用?this
?關鍵字標記目標類型。?訪問權限:
- 擴展方法只能訪問目標類型的 ?**
public
?成員**?(如?Product
?的?Name
、Price
)。- 無法訪問?
private
?或?protected
?成員。?命名空間依賴:
- 若擴展方法定義在命名空間?
MyExtensions
?中,使用時需通過?using MyExtensions;
?引入。?
關鍵規則
-
?隱式傳遞實例:
- 調用擴展方法時,實例對象(如?
product
)會自動成為靜態方法的第一個參數。 - 你無需(也不能)手動傳遞該參數。
- 調用擴展方法時,實例對象(如?
-
?附加參數:
- 擴展方法定義中除第一個參數(
this
參數)外的其他參數,需在調用時顯式傳入。 - 例如?
IsInStock(30)
?中的?30
?對應方法定義中的?requiredQuantity
。
- 擴展方法定義中除第一個參數(
補充示例:為系統自帶類int拓展的方法:
public static class IntExtensions {// 判斷數字是否為偶數public static bool IsEven(this int number) {return number % 2 == 0;}// 計算數字的平方public static int Square(this int number) {return number * number;}
}// 使用
int num = 5;
Console.WriteLine(num.IsEven()); // 輸出 False
Console.WriteLine(num.Square()); // 輸出 25
3. ?注意事項
- 拓展方法優先級低于類的實例方法。????????
- 無法訪問類型的私有成員。
- 需通過命名空間引入拓展方法所在的類。
三、什么是運算符重載?
????????運算符重載(Operator Overloading)?允許為自定義類型重新定義運算符的行為?(如?+
,?==
,?>
?等)。
概念
讓自定義的類和結構體
能夠運用運算符?使用關鍵字
operator特點
1.一定是一個公共的靜態方法
2.返回值寫在operator前
3.邏輯處理自定義作用
讓自定義類和結構體對象可以進行運算
注意
1.條件運算符需要成對出現
2.一個符號可以多次重載
3.不能使用ref out?
- ?核心規則:
- 使用?
operator
?關鍵字定義。 - 必須是?
public static
?方法。
- 使用?
- ?示例:為自定義的?
Vector
?類重載?+
?運算符。 - 語法:public static 返回類型 operator 運算符(參數列表)
public class Vector {public int X { get; }public int Y { get; }public Vector(int x, int y) { X = x; Y = y; }public static Vector operator +(Vector a, Vector b) {return new Vector(a.X + b.X, a.Y + b.Y);}
}// 使用
Vector v1 = new Vector(1, 2);
Vector v2 = new Vector(3, 4);
Vector sum = v1 + v2; // sum.X=4, sum.Y=6
四、運算符重載有啥用?怎么寫?
1. ?核心用途
- ?自然語義:讓自定義類型支持直觀的運算符操作(如復數相加、矩陣乘法)。
- ?提高可讀性:用?
a + b
?替代?a.Add(b)
。
2. ?編寫步驟
- ?定義運算符方法:指定運算符和操作數類型。
- ?實現運算邏輯:返回計算結果
語法:public static 返回類型 operator 運算符(參數列表)
如下是一個用來計算溫度的? “? + ”:
public class Temperature {public double Celsius { get; }public Temperature(double celsius) { Celsius = celsius; }public static Temperature operator +(Temperature t1, Temperature t2) {return new Temperature(t1.Celsius + t2.Celsius);}
}
3. ?可重載的運算符
?運算符類型 | ?示例 |
---|---|
算術運算符 | + ,?- ,?* ,?/ ,?% |
比較運算符 | == ,?!= ,?> ,?< ,?>= ,?<= |
轉換運算符 | implicit ?或?explicit |
4. ?注意事項
- 必須成對重載(如重載?
==
?必須同時重載?!=
)。 - 不能重載賦值運算符(如?
=
、+=
)。 - 避免過度使用導致邏輯混亂(如讓?
+
?執行減法操作)。
五、總結
?對比表:拓展方法 vs 運算符重載
?特性 | ?拓展方法 | ?運算符重載 |
---|---|---|
?核心目的 | 擴展現有類型的功能 | 自定義類型支持運算符操作 |
?語法要求 | 靜態類 +?this ?參數 | public static operator |
?適用場景 | 工具方法、鏈式調用、LINQ | 數學運算、集合操作、語義化操作 |
?限制 | 無法訪問私有成員 | 需成對重載、不能重載所有運算符 |
一句話記憶:
- 拓展方法:“別人家的孩子,我來教他新技能。”
- 運算符重載:“我的對象,加減乘除我說了算!”
掌握這兩個特性,讓你的C#代碼像自然語言一樣直觀!