ホームページ >バックエンド開発 >C++ >C# 拡張メソッドを識別するためにリフレクションをどのように使用できますか?

C# 拡張メソッドを識別するためにリフレクションをどのように使用できますか?

Susan Sarandon
Susan Sarandonオリジナル
2025-01-06 09:01:42553ブラウズ

How Can Reflection Be Used to Identify C# Extension Methods?

リフレクションを使用した拡張メソッドの識別

C# プログラミングの領域では、メソッドが拡張メソッドかどうかを識別するためにリフレクションをどのように利用できるかという疑問が生じます。拡張メソッドとしてクラスに組み込まれていますか?この問い合わせは、単体テスト中に特定の拡張メソッドがクラスに適切に追加されたことを確認する必要があることから生じています。このようなアプローチは、同一のメソッドがクラス自体に追加される可能性があり、コンパイラーが後者のバージョンを選択する可能性がある状況に特に関連します。

技術的な取り組み

このタスクを達成するには、必要な拡張メソッドが存在する可能性があるプロジェクト内のすべてのアセンブリを詳しく調べる必要があります。私たちの目的は、[ExtensionAttribute] 属性で装飾されたクラスを見つけて、その後、同じ装飾を持つそれらのクラス内のメソッドを調べることです。最後のステップでは、各メソッドの最初のパラメータの型を精査して、それが関心のある型に対応しているかどうかを確認します。

コードの概要

より実践的な図を提供するために、拡張と非拡張の両方を含むさまざまなタイプのメソッドの存在をシミュレートする付属のコード スニペットを検討してください。 Methods:

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。