Закрытия и лямбда в C#

Можно всегда использовать определение xor для вычислений его из других логических операций:

(a and not b) or (not a and b)

, Но это является немного слишком подробным для меня и не является особенно ясным на первый взгляд. Другой способ сделать это:

bool(a) ^ bool(b)

оператор XOR на двух булевских переменных является логическим xor (в отличие от этого, на ints, где это является поразрядным). Который имеет смысл, так как bool просто подкласс int , но реализован, чтобы только иметь значения 0 и 1. И логический xor эквивалентен поразрядному xor, когда домен ограничивается 0 и 1.

Так эти logical_xor функция была бы реализована как:

def logical_xor(str1, str2):
    return bool(str1) ^ bool(str2)

Кредит к [1 111] Nick Coghlan в списке рассылки Python 3000 .

11
задан lJohnson 20 August 2009 в 15:24
поделиться

5 ответов

Да, FindAll создаст новый список. Вам нужно "Where", которое вернет объект IEnumerable, который знает, как перебирать ваш существующий список:

foreach (string name in names.Where(n => n.StartsWith("C") ) ) 
{
    Console.WriteLine(name);
}

Но в этом коде нет закрытия, потому что нет локальной переменной для захвата.

15
ответ дан 3 December 2019 в 02:41
поделиться

Другие ответы, которые говорят: используйте "Где" правильно. Дополнительный момент: вы также можете использовать синтаксис понимания запроса, чтобы "Где" выглядело лучше:

   var query = from name in names where name.StartsWith("C") select name;
   foreach(var result in query) Console.WriteLine(result);

Обратите внимание, что из соображений стилистики я рекомендую, чтобы выражения не имели побочных эффектов, а у операторов всегда были побочные эффекты. Поэтому я лично использовал бы оператор foreach , а не подвыражение ForEach для выполнения побочного эффекта вывода. Многие с этим не согласны, но я думаю, что это делает код более понятным.

12
ответ дан 3 December 2019 в 02:41
поделиться

Вы должны использовать Where вместо FindAll . Где будет перебирать коллекцию для вашего условия и позволит вам выполнить ваше действие, вместо того, чтобы создавать новую коллекцию, которая соответствует вашему условию, а затем перебирать THAT и выполнять ваше действие.

2
ответ дан 3 December 2019 в 02:41
поделиться

Вы правы в том, что использование метода List .FindAll создаст и вернет новый List .

Если вы можете использовать LINQ, то есть много методов, которые передают результаты по одному элементу за раз, где это возможно, вместо того, чтобы возвращать полностью заполненную коллекцию:

foreach (var i in names.Where(x => x.StartsWith("C")))
{
    Console.WriteLine(i);
}

Нет встроенного метода ForEach который действует на IEnumerable , но написать собственное расширение, если вам действительно нужна эта функция, тривиально:

names.Where(x => x.StartsWith("C")).ForEach(Console.WriteLine);

// ...

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (T item in source)
    {
        action(item);
    }
}
2
ответ дан 3 December 2019 в 02:41
поделиться

Что делает выражение конкретно замыканием , так это лексическая область видимости, нет?

 string prefix = "C"; 
// значение префикса, включенного в область видимости 
names.FindAll (x => x.StartsWith (префикс)). ForEach (...); 

или даже

 Func filter = null;

{
 префикс строки = "C";
 // значение префикса, включенного в область видимости
 filter = x => x.StartsWith (префикс); 
}

// находим все имена, начинающиеся с "C"
names.FindAll (фильтр) .ForEach (...); 

Или я что-то упускаю или делаю необоснованные предположения?

0
ответ дан 3 December 2019 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: