兼容对象的{C #umum用法

时间:2015-12-27 23:45:03

标签: c# enums

在我的场景中,我有一个名为Person的类。我需要测试某些人是否兼容并返回bool值。我正在考虑使用枚举设置来更容易地测试这些兼容性测试。但是我不熟悉enum,并且希望有人可以解释一下,或者帮助演示如何在我的情况下使用它。

我认为最简单的方法是为每个Person分配一个id以及一个兼容性列表以及该ID。下面是一些伪代码,展示了我的意思。我还不清楚如何使用枚举进行设置。

分配给每个类对象的ID

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]

我想要执行的测试并返回一个bool值。

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

3 个答案:

答案 0 :(得分:3)

老实说,enum不是解决方案。与“兼容性检查器”最接近的类比可能是.NET中的EqualityComparer<T>。这是一个单独的课程。

比较“两个人兼容”真的不属于Person类。这取决于您比较它们的兼容性衡量标准以及随着时间的推移,比较可能会发生变化,或者您可能会添加其他兼容性比较器。

因此,而不是enum创建一个CompatibilityComparer类。现在这有一个方法.IsCompatible(Person a, Person b),在该方法中你可以使用字典,数据库查找,基于a和b的加权值的复杂计算,或者你想要的任何其他方法。

private static readonly CompatibilityComparer comparer 
      = new CompatibilityComparer();

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

请参阅separation of concernssingle responsibility principle

理想情况下,您的比较器也可以在接口IPerson而不是具体的类Person上运行,因此您可以使用模拟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);
}

您还可以将兼容性图表表示为兼容人员ID对,2D方阵或任何其他图表表示。

如果您确实拥有内存中的所有Person个对象,静态定义,最好有一个Dictionary<Person, List<Person>>,尽管在某个时候必须要问,“这里的真实环境是什么? “,这不是一个有趣的问题,直到有成千上万的人,他们在数据库中,然后再次需要不同的方法。

'兼容性'是如何决定的? a)由人在数据库中输入数据或b)通过某种算法?如果前者那么将涉及Ids和数据库中的“兼容性”表,其中两个外键返回到people表(就像字典一样用来说明)。如果后者为什么不是代码?

答案 1 :(得分:0)

你想要的是带有flags属性的枚举类型:

    [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 for bit flags。

答案 2 :(得分: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中进行。这种技术允许您添加&#34;属性&#34;您的枚举,如要求兼容性或获取兼容人员列表的能力。但是,如果它比这更复杂,我建议选择一个类。

相比之下@OwlSolo的答案确实有效,但有些限制,但如果您的要求与描述一致,我建议您只添加一个便利扩展方法,该方法隐藏逻辑位计算并取[Flags]方法

盲目编写代码,因此编译错误不保证