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