Подтвердить что ты не робот

Является ли эта сложная вещь равной этому? или это? или это?

Скажем, я работаю с объектом класса thing. То, как я получаю этот объект, немного многословно:

 BigObjectThing.Uncle.PreferredInputStream.NthRelative(5)

Я хотел бы видеть, равен ли этот thing x или y или z. Наивный способ написать это может быть:

 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

но С# не позволяет этого.

Существует ли С# -идиоматический способ записи этого теста в виде одного выражения?

4b9b3361

Ответ 1

Просто используйте переменную:

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));

Ответ 2

Метод расширения будет имитировать это:

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);

С# не имеет синтаксиса по умолчанию для такого OR-подобного сравнения afaik.

Ответ 3

Как указывали другие, коллекция является одним из способов сделать это. Если вы хотели бы иметь немного больше гибкости, чем использовать Contains (который действительно позволяет протестировать x.Equals(y)) и даже поддерживать привязку &= в дополнении к |=, я бы предложил Any или All методы расширения, встроенные в .NET.

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);

Ответ 4

Сначала вы можете поместить свои объекты в 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)))
{
    ...
}

Ответ 5

Есть ли такой материал в одном выражении? Это требует моего безумного умения 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!");

Я не говорю, что вы должны делать это таким образом, но эй, вы получите логический результат, вы можете проверить любое количество значений вместо x, y и z! Кроме того, это не ограничивает вас сравнением с ==, вы можете использовать все, что вам нравится на своем месте.

И эй, одно выражение!

Шутки в сторону, придумывая странные способы делать то, что вы хотели сделать, это весело, но вы действительно должны поместить результат BigObjectThing.Uncle.PreferredInputStream.NthRelative(5) в переменную!