Получение всех типов, которые реализуют интерфейс

Java double s находятся в формате IEEE-754 , поэтому они имеют 52-битную дробь; между любыми двумя соседними степенями двух (включая один и исключая следующий), поэтому будет 2 до 52-й степени, другой double s (т. е. 4503599627370496 из них). Например, это число различных double s между 0,5 включенными и 1.0 исключенными, и точно, что многие также лежат между 1.0 включенными и 2.0 исключенными и т. Д.

Подсчет doubles между 0.0 и 1.0 сложнее, чем между двумя степенями, потому что в этом диапазоне есть много полномочий из двух, а также попадает в тернистые проблемы денормализованных чисел. 10 из 11 бит экспонентов охватывают диапазон, о котором идет речь, поэтому, включая денормализованные числа (и, я думаю, несколько видов NaN), вы имели бы 1024 раз double s как лежащие между степенями двух - в любом случае не более 2**62. Исключение denormalized & amp; c, я считаю, что счет будет 1023 раза 2**52.

Для произвольного диапазона, например «100-1100,1», это еще сложнее, потому что верхняя граница не может быть точно представлена ​​как double (не являясь точным кратным любой мощности двух). В качестве удобного приближения, поскольку прогрессия между степенями двух линейна, вы можете сказать, что указанный диапазон равен 0.1 / 64 th промежутка между окружающими силами двух (64 и 128), поэтому вы ожидаете, что

(0.1 / 64) * 2**52

отличается double s - который приходит к 7036874417766.4004 ... дает или принимает один или два; -).

505
задан Ondrej Janacek 30 September 2014 в 12:20
поделиться

7 ответов

Мой был бы этим в c# 3.0:)

var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => type.IsAssignableFrom(p));

В основном, наименьшее количество объема повторений всегда будет:

loop assemblies  
 loop types  
  see if implemented.
746
ответ дан Darren Kopp 30 September 2014 в 12:20
поделиться

Нет никакого простого способа (с точки зрения производительности), чтобы сделать то, что Вы хотите сделать.

Отражение работает с блоками и типами главным образом, таким образом, необходимо будет получить все типы блока и запросить их для правильного интерфейса. Вот пример:

Assembly asm = Assembly.Load("MyAssembly");
Type[] types = asm.GetTypes();
Type[] result = types.where(x => x.GetInterface("IMyInterface") != null);

, Который получит Вас все типы, которые реализуют IMyInterface в блоке MyAssembly

2
ответ дан Jorge Córdoba 30 September 2014 в 12:20
поделиться

Вы могли использовать некоторый LINQ для получения списка:

var types = from type in this.GetType().Assembly.GetTypes()
            where type is ISomeInterface
            select type;

, Но действительно, который более читаем?

-3
ответ дан Ryan Rinaldi 30 September 2014 в 12:20
поделиться

Редактирование: я только что видел редактирование, чтобы разъяснить, что исходный вопрос был для сокращения повторений / код, и это - все хорошо и хороший как осуществление, но в реальных ситуациях Вы собираетесь хотеть самую быструю реализацию, независимо от того, как прохладный базовый LINQ смотрит.

Вот мой метод Utils для итерации через загруженные типы. Это обрабатывает регулярные классы, а также интерфейсы, и excludeSystemTypes опция ускоряет вещи чрезвычайно при поиске реализаций в собственном / сторонняя кодовая база.

public static List<Type> GetSubclassesOf(this Type type, bool excludeSystemTypes) {
    List<Type> list = new List<Type>();
    IEnumerator enumerator = Thread.GetDomain().GetAssemblies().GetEnumerator();
    while (enumerator.MoveNext()) {
        try {
            Type[] types = ((Assembly) enumerator.Current).GetTypes();
            if (!excludeSystemTypes || (excludeSystemTypes && !((Assembly) enumerator.Current).FullName.StartsWith("System."))) {
                IEnumerator enumerator2 = types.GetEnumerator();
                while (enumerator2.MoveNext()) {
                    Type current = (Type) enumerator2.Current;
                    if (type.IsInterface) {
                        if (current.GetInterface(type.FullName) != null) {
                            list.Add(current);
                        }
                    } else if (current.IsSubclassOf(type)) {
                        list.Add(current);
                    }
                }
            }
        } catch {
        }
    }
    return list;
}

Это не симпатично, я признаю.

5
ответ дан buræquete 30 September 2014 в 12:20
поделиться

цикл посредством всех загруженных блоков, цикл через все их типы и проверка, если они реализуют интерфейс.

что-то как:

Type ti = typeof(IYourInterface);
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) {
    foreach (Type t in asm.GetTypes()) {
        if (ti.IsAssignableFrom(t)) {
            // here's your type in t
        }
    }
}
18
ответ дан buræquete 30 September 2014 в 12:20
поделиться

Для нахождения всех типов в блоке, которые реализуют интерфейс IFoo:

var results = from type in someAssembly.GetTypes()
              where typeof(IFoo).IsAssignableFrom(type)
              select type;

Примечание, что предложение Ryan Rinaldi было неправильным. Это возвратит 0 типов. Вы не можете записать

where type is IFoo

, потому что типом является Система. Введите экземпляр, и никогда не будет иметь типа IFoo. Вместо этого Вы проверяете, чтобы видеть, является ли IFoo присваиваемым от типа. Это получит Ваши ожидаемые результаты.

кроме того, предложение Adam Wright, которое в настоящее время отмечается как ответ, является неправильным также, и по той же причине. Во времени выполнения Вы будете видеть, что 0 типов возвращаются, потому что вся Система. Экземпляры типа не были конструкторами IFoo.

54
ответ дан Judah Gabriel Himango 30 September 2014 в 12:20
поделиться
   public IList<T> GetClassByType<T>()
   {
        return AppDomain.CurrentDomain.GetAssemblies()
                          .SelectMany(s => s.GetTypes())
                          .ToList(p => typeof(T)
                          .IsAssignableFrom(p) && !p.IsAbstract && !p.IsInterface)
                          .SelectList(c => (T)Activator.CreateInstance(c));
   }
0
ответ дан 22 November 2019 в 22:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: