Найти классы, которые реализуют интерфейс или являющиеся потомками данного класса в 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.