2015-12-27 2 views
-1

В моем сценарии у меня есть класс под названием Person. Мне нужно проверить, совместимы ли определенные люди или нет, и вернуть значение bool. Я думал об использовании настройки перечисления, чтобы было легче протестировать эти тесты совместимости. Однако я не знаком с перечислением и надеялся, что кто-то может пролить свет или помочь продемонстрировать, как я буду использовать его в своем случае.C# enum использование для совместимых объектов

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

удостоверения личности присваивается каждому объекту класса

1 = Person(John) 
2 = Person(Kevin) 
3 = Person(Michelle) 
4 = Person(Krystal) 
5 = Person(Leslie) 

Совместимость список

1 = [2,4] 
2 = [1,3,5] 
3 = [2,5] 
4 = [1] 
5 = [2,3] 

тестирования я хочу выполнить и возвращают булево значение.

If (Person(John) compatible with Person(Krystal)) 
{return true}else{return false} 
+0

Вы можете показать, как выглядит ваш фактический enum, почему вы не сравниваете значения Enums. Возможно, эта ссылка может помочь пролить свет на то, как сравнивать значения Enum http://stackoverflow.com/questions/19537083/ c-sharp-enum-how-to-compare-value – MethodMan

ответ

3

Честно, enum не является решением для этого. Ближайшей аналогией с вашей «проверкой совместимости», вероятно, будет EqualityComparer<T> в .NET. Это отдельный класс.

Сравнение «совместимы с двумя людьми» действительно не принадлежит классу Person. Это зависит от того, какую меру совместимости вы сравниваете, и со временем это сравнение может измениться, или вы можете добавить другие сопоставители совместимости.

Итак, вместо enum создайте класс CompatibilityComparer. На данный момент это имеет один метод .IsCompatible(Person a, Person b), и внутри этого метода вы можете использовать словарь, поиск базы данных, сложный расчет на основе взвешенных значений из a и b или любого другого, что вы хотите.

private static readonly CompatibilityComparer comparer 
     = new CompatibilityComparer(); 

... 
if (comparer.IsCompatible(john, krystal)) ... 

См separation of concerns и single responsibility principle.

В идеале ваш компаратор также будет работать на интерфейсе IPerson, а не на конкретном классе Person, чтобы вы могли легче его протестировать с помощью mock IPerson объектов.

Простейший пример, используя словарь совместимых людей может быть:

Dictionary<int, int[]> matrix = new Dictionary<int, int[]>(); 

// You could initialize this statically, or better yet, use Lazy<> 
static CompatibilityComparer() 
{ 
    matrix[1] = new[] { 2, 4 }; 
    ... 

} 

public bool IsCompatible(Person a, Person b) 
{ 
    return matrix[a.Id].Contains(b.Id); 
} 

Вы также можете представить ваш график совместимости в виде списка пара совместимых людей идентификаторов, как 2D квадратной матрицы, или любые другое представление графика.

Если у вас действительно есть все Person объекты в памяти, статически определить, было бы лучше иметь Dictionary<Person, List<Person>>, хотя в какой-то момент один должен спросить, «что реальная среда здесь?», Это не интересная проблема пока не будет тысяч людей, и они находятся в базе данных, а затем нужен другой подход.

Как была выбрана «совместимость»? а) человеком, вводящим данные в базу данных или б) некоторым алгоритмом? Если первое, то это будет включать в себя идентификаторы и таблицу совместимости в базе данных с двумя внешними ключами назад к таблице людей (например, словарь предназначен для иллюстрации). И если последнее, почему это не так в коде?

+0

Отличная идея, просто полностью забыл о сравнении. В любом случае метод расширения может помочь сделать код менее подробным и, следовательно, более читаемым. –

+0

@ian mercer, о котором вы упомянули внутри этого метода, я могу использовать словарь, поиск базы данных ... Можете ли вы привести пример того, что может выглядеть так, чтобы я мог понять, что я буду делать. – JokerMartini

+0

@JokerMartini Я добавил пример, используя словарь. –

0

То, что вы хотите, это перечисление с атрибутом флаги:

[Flags] 
    enum MyCompatibilities 
    { 
     a = 1, 
     b = 2, 
     c = 4, 
     d = 8 
    } 

При этом вы можете назначить количество перечислений элементов, которые применяются.

MYCompatibility comp = MYCompatibility.a | MYCompatibility.b; 

| является логическим OR, и это означает, что переменная comp обладает свойствами a, а также b

Вы можете выяснить, является ли определенная совместимость устанавливается с помощью битового сравнения:

if (comp & MYCompatibility.a= != 0) 

или с логикой, предоставленной атрибутом [Flags]:

if (comp.HasFlag(MYCompatibility.a)) 

Для внутренних действий этого, google для бит-флагов.

+0

Вы правы, я допустил ошибку здесь. – srandppl

0

Я предлагаю вам использовать перечисления вместе с методами расширения. Позвольте мне объяснить, как это сработает для вас.

public enum Person 
{ 
    John  = 1, 
    Kevin = 2, 
    Michelle = 3, 
    Krystal = 4, 
    Leslie = 5 
} 

Здесь у вас есть идентификаторы с соответствующим числом, установленным явно. Однако эта ассоциация чисел является необязательной и может быть отменена.

public static class PersonExtensions 
{ 
    private Dictionary<Person,List<Person>> compatiblePersons = createCompatiblePersons(); 
    private static Dictionary<Person,List<Person>> createCompatiblePersons() 
    { 
     var d = new Dictionary<Person,List<Person>>; 
     // put your compatibilities here 
     d[Person.John] = new List() 
     { 
      Person.Kevin, 
      Person.Krystal 
     }; 
     return d; 
    } 

    public static List<Person> GetCompatiblePersons(this Person person) 
    { 
     return compatiblePersons(person); 
    } 

    public static bool IsCompatibleWith(this Person person, Person other) 
    { 
     return this.GetCompatiblePersons().Contains(other); 
    } 
} 

Это static class позволяет использовать методы расширения на любой Person, например, например, Person.John.IsCompatibleWith(Person.Michelle) вернет false в этом случае. Ассоциация создана в заявке Dictionary. Этот метод позволяет добавлять «свойства» к вашим перечислениям, как возможность запрашивать совместимость или получать список совместимых лиц. Тем не менее, я бы предложил выбрать класс, если он становится более сложным, чем это.

Ответ от @OwlSolo в отличие от этой работы, но несколько ограничен, но если ваши требования так же описаны, я бы рекомендовал просто добавить метод расширения удобства, который скрывает вычисления логических бит и принимает подход [Flags].

Код, написанный вслепую, поэтому никаких гарантий на наличие ошибок компиляции

Смежные вопросы