透過反射辨識擴充方法
在C# 程式領域,出現了這樣的問題:我們如何利用反射來辨別方法是否存在已作為擴展方法合併到類別中?此查詢源自於需要驗證在單元測試期間是否已將特定擴充方法正確新增至類別。這種方法在可能將相同方法添加到類別本身的情況下特別相關,可能導致編譯器選擇後一個版本。
技術之旅
為了完成此任務,我們需要深入研究專案中的所有程序集,其中可能存在所需的擴展方法。我們的目標是找到帶有 [ExtensionAttribute] 屬性裝飾的類,然後檢查這些類中也帶有相同裝飾的任何方法。最後一步涉及仔細檢查每個方法的第一個參數的類型,以確定它是否對應到我們感興趣的類型。
程式碼概覽
為了提供更實際的說明,請考慮隨附的程式碼片段,它模擬了各種類型方法的存在,包括擴展和非擴展方法:
using System; using System.Runtime.CompilerServices; public static class FirstExtensions { public static void Foo(this string x) { } public static void Bar(string x) { } // Not an extension method public static void Baz(this int x) { } // Not on string } public static class SecondExtensions { public static void Quux(this string x) { } } class Program { static void Main() { // Get the assembly containing the current type Assembly thisAssembly = typeof(Program).Assembly; // Enumerate all extension methods for the string type in the assembly foreach (MethodInfo method in GetExtensionMethods(thisAssembly, typeof(string))) { Console.WriteLine(method.Name); } } static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly, Type extendedType) { // Determine if the extended type is a generic type definition var isGenericTypeDefinition = extendedType.IsGenericType && extendedType.IsTypeDefinition; // Query for extension methods in the assembly return from type in assembly.GetTypes() where type.IsSealed && !type.IsGenericType && !type.IsNested from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where method.IsDefined(typeof(ExtensionAttribute), false) where isGenericTypeDefinition ? method.GetParameters()[0].ParameterType.IsGenericType && method.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == extendedType : method.GetParameters()[0].ParameterType == extendedType select method; } }
執行時,此程式碼僅擷取並顯示為包含Program 類別的程式集中的字串類型定義的擴充方法。顯示的方法將是“Foo”和“Quux”,因為它們都符合擴充方法的標準。
總之,反射為內省和識別程序集中的擴展方法提供了一種有價值的機制。此技術對於測試場景特別有用,可確保成功實現預期的擴展方法。
以上是如何使用反射來識別 C# 擴展方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!