2016-04-15 2 views
0
  • У меня есть общий интерфейс, который требует метода чтения и ключа. Я хочу использовать отражение, чтобы получить экземпляр каждой реализации.
  • Как только у меня есть реализация, я хочу получить ее ключ и сохранить ключ и экземпляр в словаре.
  • В конце концов, у меня будет метод, в котором я передам ключ и байт [], он будет искать ключ в словаре и использовать экземпляр, который он извлекает для чтения байта [], и возвращает object.
  • Надеюсь, это понятно, если нет, я могу ответить на вопросы в комментариях.
  • В этом примере есть только int и string, но в моей реальной реализации у меня будет много других типов.

ЦельКак использовать отражение для получения реализаций общего интерфейса

Чтобы иметь словарь с 2 записей, хранящихся в качестве таковых:

  • 43, IRead<int> new Reader()
  • 61, IRead<string> new Reader()

public interface IRead<T> 
{ 
    T Read(bool[] binary); 
    int Key(T type); 
} 

public class Reader : IRead<int>, IRead<string> 
{ 
    int IRead<int>.Read(byte[] binary) 
    { 
     // does stuff 
     returns 4; 
    } 

    public int Key(int type) { return 43; } 

    string IRead<string>.Read(byte[] binary) 
    { 
     // does stuff 
     returns "example"; 
    } 

    public int Key(string type) { return 61; } 

    static StreamProcessor() 
    { 
     // Here I want to get the definitions 
    } 
} 
+0

Вы не можете определить на основе интерфейса 'IRead ', что реализация будет иметь конструктор без параметров. Итак, как вы знаете, что сможете создать экземпляр каждого типа, который вы найдете? –

+0

@ScottHannen Я просто хочу, чтобы Reader читал тип, определенный в словаре – JacobVoller

+0

Похоже, вы ищете какую-то реализацию контейнера IoC. Посмотрите на [this] (http://stackoverflow.com/questions/28509317/get-all-types-that-implement-an-interface-in-unity) вопрос и предлагаемые ответы. –

ответ

0

Пожалуйста, задайте вопрос, который компилирует. Это делает жизнь проще для всех (возможно, вашего ответа, потому что псевдокод вы написали неправильно?)

В любом случае, это будет получить все типы, которые реализуют IRead<>:

var types = GetType().Assembly.GetTypes() 
.Select(t => new 
{ 
    Type = t, 
    MatchingInterfaces = t.GetInterfaces() 
          .Where(i => i.GetGenericTypeDefinition() == typeof(IRead<>)) 
}) 
.Where(t => t.MatchingInterfaces.Any()) 

Вашего предварительного условия возвращения ключ не имеет большого смысла. Вы не можете найти все экземпляров из IRead<>. И вам нужен экземпляр, чтобы дать вам ключ.

Например, что бы ваш словарь выглядеть, если у вас этот код:

var readerOne = new Reader(); 
var readerTwo = new Reader(); 

Какой экземпляр идет в словарь?

Ближайшие вы можете получить это:

  1. Передайте методу список объектов и вернуть ключ тех случаев
  2. Создать фиктивный экземпляр каждого типа, чтобы получить ключ
  3. Марки ключевой метод статический, а не часть интерфейса.
+0

#Rob Что не скомпилировалось? Это C# 6.0, если вы не используете это, может быть? – JacobVoller

0

Я предлагаю разбить это, потому что есть несколько разных вещей, которые вы пытаетесь сделать - некоторые из них ясны, а некоторые нет.

Сначала вы хотите получить типы, которые реализуют IReader:

public IEnumerable<Type> GetTypes<TAssignableFrom>() 
{ 
    return this.GetType().Assembly.GetTypes() 
     .Where(type => type.IsAssignableFrom(typeof (TAssignableFrom))); 
} 

Что вы хотите сделать с этими типами? Если вы хотите создать экземпляр каждого типа, то либо они должны иметь конструкторы без параметров, либо иначе идентичные конструкторы, или вам нужно будет использовать некоторый контейнер для инъекций зависимостей.

Предположим, что у них будут безпараметрические конструкторы. Мы можем обновить вышеуказанное до

public IEnumerable<Type> GetTypes<TAssignableFrom>() 
{ 
    return this.GetType().Assembly.GetTypes() 
     .Where(type => type.IsAssignableFrom(typeof (TAssignableFrom)) 
      && type.GetConstructor(Type.EmptyTypes) != null 
     ); 
} 

Теперь у вас есть куча типов, которые вы можете создать.

Оттуда он становится довольно нечетким. Что вы будете делать с этими типами? Не очень удобно помещать их в словарь, потому что все они разные.