Найти непосредственные реализованные интерфейсы по типу - PullRequest
7 голосов
/ 13 января 2010

При вызове typeof (Bar) .GetInterfaces () в следующем сценарии метод возвращает IFoo и IBar.

interface IFoo {}<br> interface IBar : IFoo {}<br> class Bar : IBar {}

Есть ли способ, которым я могу найти только непосредственный интерфейс (IBar) на Bar?

Ответы [ 3 ]

13 голосов
/ 13 января 2010

Нет, в скомпилированном коде нет понятия "немедленный" интерфейс. Ваш класс эффективно скомпилирован как:

class Bar : IBar, IFoo { }

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

static IEnumerable<Type> GetImmediateInterfaces(Type type)
{
    var interfaces = type.GetInterfaces();
    var result = new HashSet<Type>(interfaces);
    foreach (Type i in interfaces)
        result.ExceptWith(i.GetInterfaces());
    return result;
}
1 голос
/ 13 января 2010
public interface IRoo { }
public interface ISoo : IRoo { }
public interface IMoo : ISoo { }
public interface IGoo : IMoo { }
public interface IFoo : IGoo { }
public interface IBar : IFoo { }
public class Bar : IBar { }

private void button1_Click(object sender, EventArgs e) {
    Type[] interfaces = typeof(Bar).GetInterfaces();    
    Type immediateInterface = GetPrimaryInterface(interfaces);
    // IBar
}

public Type GetPrimaryInterface(Type[] interfaces)
{
    if (interfaces.Length == 0) return null;
    if (interfaces.Length == 1) return interfaces[0];

    Dictionary<Type, int> typeScores = new Dictionary<Type, int>();
    foreach (Type t in interfaces)
        typeScores.Add(t, 0);

    foreach (Type t in interfaces)
        foreach (Type t1 in interfaces)
            if (t.IsAssignableFrom(t1))
                typeScores[t1]++;

    Type winner = null;
    int bestScore = -1;
    foreach (KeyValuePair<Type, int> pair in typeScores) {
        if (pair.Value > bestScore) {
            bestScore = pair.Value;
            winner = pair.Key;
        }
    }
    return winner;
}
0 голосов
/ 18 февраля 2016

Выбирает интерфейс с самым длинным деревом наследования.

typeof(Bar)
  .GetInterfaces()
  .OrderByDescending(i => i.GetInterfaces().Length)
  .FirstOrDefault()

Этого было достаточно для моего варианта использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...