2016-04-08 4 views
1

У меня есть следующая реализация для сравнения двух объектов.получить объект класса на основе общего интерфейса

public interface IEqualityDefinition<T> 
{ 
    bool Compare(object source, T target); 
} 

public class BlockEqualityDefinition : IEqualityDefinition<Block> 
{ 
    public bool Compare(object source, Block target) 
    { 
     // compare stuff.. 
     return false; 
    } 
} 

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

public bool Compare(object source, object target) 
{ 
    // Here i want something else 
    IEqualityDefinition definition = new BlockEqualityDefinition(); 

    return definition.Compare(source, target); 
} 

В этом методе я хочу, чтобы создать экземпляр класса на основе параметра «целевой». Например, когда параметр «target» содержит объект «Block», я хочу, чтобы правый класс EqualityDefinition вызывался, чтобы сделать материал сравнения для меня.

Каков наилучший способ для этого? Я не могу понять это сейчас. Благодарим за помощь!

ответ

0

Два варианта из верхней части моей головы:

  • Создать карту в коде, где вы храните ваши реализации

    Dictionary<Type, IEqualityDefinition> 
    

    Добавить свои реализации к нему

    EqualityMap.Add(typeof(Block), new BlockEqualityDefinition) 
    

    И запросите его по типу, который вы добавляете.

    EqualityMap[target.GetType()] 
    
  • Или интерфейс для сканирования всех загруженных сборок для типов imlementing разыскиваемых. Как в How do i get a list of all loaded types in C#

    Чтобы не всегда сканировать все загруженные типы, кешируйте их на карте, как в первом варианте.

0

Вы должны заглянуть в заводы. Заводская схема позволяет вам именно это.

(На самом деле не так хорошо) Пример из here:

class Factory 
{ 
    /// <summary> 
    /// Decides which class to instantiate. 
    /// </summary> 
    public static Position Get(int id) 
    { 
     switch (id) 
     { 
     case 0: 
      return new Manager(); 
     case 1: 
     case 2: 
      return new Clerk(); 
     case 3: 
     default: 
      return new Programmer(); 
     } 
    } 
} 

Но в вашем случае (на самом деле в большинстве случаев), я бы сказал, вы должны использовать перечисление вместо междунар - его лучше реорганизовать, чтобы понимать и читать:

public enum EqualityDefinitions 
{ 
    Block // or BlockEquality 
    // and more 
} 

, а затем вы можете использовать его как это:

class EqualityDefinitionFactory 
{ 
    /// <summary> 
    /// Decides which class to instantiate. 
    /// </summary> 
    public static IEqualityDefinition Get(EqualityDefinitions definition) 
    { 
     switch (definition) 
     { 
      case EqualityDefinitions.BlockEquality: 
       return new BlockEqualityDefinition(); 
      default: 
       throw new NotImplementedException("Unknown type"); 
     } 
    } 
} 
Смежные вопросы