在本文中,我们展示了如何在C#中定义和使用扩展方法。
C#扩展方法
扩展方法是可以插入现有类型的方法,无需创建新的派生类型、重新编译或以其他方式修改原始类型。
扩展方法是静态方法,但在C#中,它们就像普通的C#方法一样被调用。他们在参数中使用this
修饰符。
仅当我们使用using指令将命名空间显式导入您的源代码时,扩展方法才在范围内。
在标准库中,我们可以找到大量扩展方法,尤其是在LINQ中。
C#LINQ扩展方法
LINQ是一种内置于C#中的迷你语言,具有更高级的查询功能。
string[] words = { "falcon", "oak", "sky", "cloud", "tree", "tea", "water" }; Console.WriteLine(words.First(word => word.Length == 3)); Console.WriteLine(words.Last(word => word.Length == 3));
该示例打印具有三个字母的第一个和最后一个单词。
Console.WriteLine(words.First(word => word.Length == 3)); Console.WriteLine(words.Last(word => word.Length == 3));
First
和Last
都是在System.Linq
命名空间中定义的C#扩展方法。
$ dotnet run oak tea
C#扩展方法示例
在下面的示例中,我们向string
类型添加了一个新方法。
var msg = "We walked for hours. We saw four hawks in the sky."; int n = msg.WordCount(); Console.WriteLine(n); public static class ExtensionMethods { public static int WordCount(this string str) { return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } }
WordCount
方法是定义在静态类中的静态方法,其参数包含this
关键字。
int n = msg.WordCount();
直接在字符串上调用该方法。
$ dotnet run 11
C#扩展方法实例二
在下一个示例中,我们向int
类型添加一个扩展方法。
int x = 20; int y = -5; Console.WriteLine(x.Abs()); Console.WriteLine(y.Abs()); public static class ExtensionMethods { public static int Abs(this int val) { if (val < 0) { return -val; } return val; } }
该示例添加了Abs
方法,该方法返回给定整数的绝对值。
$ dotnet run 20 5
C#泛型扩展方法
在下一个示例中,我们为列表类型定义一个FindAll
扩展方法。
public static class ExtensionMethods { public static List<T> FindAll<T>(this List<T> vals, List<Predicate<T>> preds) { List<T> data = new List<T>(); foreach (T e in vals) { bool pass = true; foreach (Predicate<T> p in preds) { if (!(p(e))) { pass = false; break; } } if (pass) data.Add(e); } return data; } }
FindAll
方法返回填充所有指定谓词的列表元素。
public static List<T> FindAll<T>(this List<T> vals, List<Predicate<T>> preds)
FindAll
方法将通用谓词函数列表作为参数。它返回过滤后的通用列表。
var preds = new List<Predicate<int>>(); preds.Add(e => e > 0); preds.Add(e => e % 2 == 0); var vals = new List<int> {-3, -2, -1, 0, 1, 2, 3, 4}; var filtered = vals.FindAll(preds); foreach (var e in filtered) { Console.WriteLine(e); } Console.WriteLine("---------------------"); var words = new List<string> {"sky", "wrath", "wet", "sun", "pick", "who", "cloud", "war", "water", "jump", "ocean"}; var preds2 = new List<Predicate<string>>(); preds2.Add(e => e.StartsWith("w")); preds2.Add(e => e.Length == 3); var filtered2 = words.FindAll(preds2); foreach (var e in filtered2) { Console.WriteLine(e); }
我们定义了两个列表:一个整数列表和一个字符串列表。从整数列表中,我们过滤掉所有正偶数。从字符串列表中,我们得到所有以’w’开头且具有三个字母的单词。
$ dotnet run 2 4 --------------------- wet who war
C#Base64扩展方法
在下面的示例中,我们创建了用于编码和解码Base64数据的扩展方法。Base64是一组类似的二进制到文本编码方案,以文本字符串格式表示二进制数据。
using System.Text; namespace Base64Ex; class Program { static void Main() { string msg = "one ð and three ð"; string base64 = msg.EncodeBase64(); string msg2 = base64.DecodeBase64(); Console.WriteLine(msg); Console.WriteLine(base64); Console.WriteLine(msg2); } } static class ExtensionMethods { public static string EncodeBase64(this string value) { byte[] data = Encoding.UTF8.GetBytes(value); return Convert.ToBase64String(data); } public static string DecodeBase64(this string value) { byte[] data = System.Convert.FromBase64String(value); return Encoding.UTF8.GetString(data); } }
程序创建了EncodeBase64
和DecodeBase64
扩展方法。
string msg = "one ð and three ð"; string base64 = msg.EncodeBase64(); string msg2 = base64.DecodeBase64();
可以直接在字符串上调用扩展方法。
$ dotnet run one ð and three ð b25lIPCfkJggYW5kIHRocmVlIPCfkIs= one ð and three ð
在本文中,我们使用了C#中的扩展方法。
列出所有C#教程。