这件大事复杂吗?或这个?还是这个?

时间:2015-06-04 17:15:08

标签: c# operators idiomatic

让我们说我正在使用班级thing的对象。我得到这个对象的方式有点罗嗦:

 BigObjectThing.Uncle.PreferredInputStream.NthRelative(5)

我想看看这个thing是否等于xyz。写这篇文章的天真方式可能是:

 BigObjectThing.Uncle.PreferredInputStream.NthRelative(5) == x ||
 BigObjectThing.Uncle.PreferredInputStream.NthRelative(5) == y ||
 BigObjectThing.Uncle.PreferredInputStream.NthRelative(5) == z

在某些语言中,我可以这样写:

 BigObjectThing.Uncle.PreferredInputStream.NthRelative(5) == x |= y |= z

但C#不允许这样做。

是否有一种C#-idiomatic方法将此测试编写为单个表达式

5 个答案:

答案 0 :(得分:46)

只需使用变量:

var relative = BigObjectThing.Uncle.PreferredInputStream.NthRelative(5);
return relative == x || relative == y || relative == z;

或者,如果你想看到更多的东西:

var relatives = new HashSet<thing>(new[] { x, y, z });
return relatives.Contains(BigObjectThing.Uncle.PreferredInputStream.NthRelative(5));

答案 1 :(得分:24)

扩展方法会模拟这个:

public static bool EqualsAny(this Thing thing, params object[] compare)
{
    return compare.Contains(thing);
}

bool result = BigObjectThing.Uncle.PreferredInputStream.NthRelative(5).EqualsAny(x, y, z);

C#没有这种类似OR的比较afaik的默认语法。

答案 2 :(得分:14)

正如其他人指出的那样,集合是你可以做到这一点的一种方式。如果您希望比使用Contains(只能让您真正测试x.Equals(y))更加灵活,甚至支持&=加上|=的链接,我和#39; d建议在.NET中内置AnyAll扩展方法。

var compares = new[] { x, y, z };
var relative = BigObjectThing.Uncle.PreferredInputStream.NthRelative(5); 

// Simulate |= behavior
return compares.Any(x => relative == x);

// Simulate &= behavior
return compares.All(x => relative == x);

// A more complex test chained by OR
return compares.Any(x => relative.SomeProperty == x.SomeProperty);

// A less readable but one-line approach
return (new [] {x, y, x}).Any(x => BigObjectThing.Uncle.PreferredInputStream.NthRelative(5) == x);

答案 3 :(得分:10)

您可以先将对象放在Collection中,然后使用Contains()

    var relatives = new Collection<Thing> { x, y, z };
    if (relatives.Contains(BigObjectThing.Uncle.PreferredInputStream.NthRelative(5)))
    {
        ...
    }

这可以进一步缩短(为了便于阅读):

if (new Collection<Thing> { x, y, z }.Contains(BigObjectThing.Uncle.PreferredInputStream.NthRelative(5)))
{
    ...
}

答案 4 :(得分:2)

一个表达式中做这些事情?这需要我的疯狂LINQ技能

工作样本(http://ideone.com/VNTFnz):

using System.Linq;

public class Test
{
    static int getStuff()
    {
        return 1;
    }

    public static void Main()
    {
        if ((from option in new int[] {1, 2, 3}
                let thing = getStuff()
                where option == thing
                select option).Any())
            System.Console.WriteLine("in the list!");
    }
}

根据您的情况翻译,它将是这样的:

        if ((from option in new Thing[] {x, y, z}
                let thing = BigObjectThing.Uncle.PreferredInputStream.NthRelative(5)
                where option == thing
                select option).Any())
            System.Console.WriteLine("in the list!");

我不是说你应该这样做,但是嘿,你得到布尔结果,你可以检查任意数量的值来代替xyz!此外,这并不限制您与==进行比较,您可以使用您喜欢的任何内容。

嘿,一个表达

除了笑话,想出奇怪的方式做你想做的事情很有趣,但你真的应该把BigObjectThing.Uncle.PreferredInputStream.NthRelative(5)的结果变成一个变量!