Найти классы, которые реализуют интерфейс или являющиеся потомками данного класса в C#

В этом примере вы можете найти классы, которые являются частью иерархии наследования или реализации. Когда вы вводите имя класса или интерфейса и нажимаете «Найти», в примере используется следующий код для поиска загруженных в настоящее время сборок для классов, являющихся потомками класса или интерфейса.

private void btnFind_Click(object sender, EventArgs e)
{
    lblNumClasses.Text = "";
    lstClasses.Items.Clear();
    Cursor = Cursors.WaitCursor;
    Refresh();

    // Список загруженных сборок.
    foreach (Assembly assembly in
        AppDomain.CurrentDomain.GetAssemblies())
    {
        Console.WriteLine(assembly.GetName().Name);
    }
    int num_assemblies =
        AppDomain.CurrentDomain.GetAssemblies().Length;
    Console.WriteLine(num_assemblies.ToString() + " assemblies");

    // Получить введенный тип.
    string type_name = txtType.Text.ToLower();
    var type_query =
        from assembly in AppDomain.CurrentDomain.GetAssemblies()
        from type in assembly.GetTypes()
        where (type.Name.ToLower() == type_name)
        select type;
    Type target_type = type_query.FirstOrDefault();

    if (target_type != null)
    {
        // Получить классы, которые назначаются целевому типу.
        var classes =
            from assembly in AppDomain.CurrentDomain.GetAssemblies()
            from type in assembly.GetTypes()
            where target_type.IsAssignableFrom(type)
            select type;

        // Отображение классов.
        foreach (Type type in classes)
        {
            lstClasses.Items.Add(type.Name);
        }
    }

    // Отображение количества классов.
    lblNumClasses.Text = lstClasses.Items.Count.ToString() + " classes";
    Cursor = Cursors.Default;
}

В коде сначала перечислены загруженные сборки в окне консоли.

Далее метод преобразует имя введенного вами типа в нижний регистр, чтобы он мог игнорировать заглавные буквы при изучении имен классов. Затем он создает запрос LINQ с именем type_name для поиска введенного вами имени класса или интерфейса. Этот запрос использует AppDomain.CurrentDomain.GetAssemblies для получения загруженных в настоящее время сборок. Он использует метод сборки GetTypes для получения типов, определенных сборками. Он исследует эти типы и выбирает те, где имя типа равно имени, которое вы ввели (преобразован в нижний регистр).

Имея (надеюсь) найденный Тип для введенного вами типа, программа определяет второй запрос LINQ. Этот запуск начинается, как и другой, чтобы найти классы, определенные загруженными сборками. На этот раз он выбирает типы, из которых можно назначить target_type, который вы ввели. Например, если вы набрали IDisposable, тогда запрос выбирает класс Form, потому что [тип IDisposable] .IsAssignableFrom (Form) is True .

Программа проходит через запрос, отображающий имена классов в ListBox с именем lstClasses.

Обратите внимание, что код только получает классы в загруженных в настоящее время сборках. Запуск этого кода фактически загружает сборки more , поэтому при первом запуске он обнаруживает 15 сборок и 889 классов, которые реализуют IDisposable. Во второй раз, когда я запускаю его, вы обнаружите 20 сборок и 925 классов, которые реализуют IDisposable.

Источник: http://csharphelper.com/blog/2017/10/find-classes-that-implement-an-interface-or-that-are-descendants-of-a-given-class-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector