Присвоить переменную результату лямбда-выражения - PullRequest
1 голос
/ 17 марта 2012

Я хотел бы выполнить что-то вроде следующего:

(clientSinceChoices =  Enumerable.Range(1949, DateTime.Now.Year - 1950)
    .Select(x => new SelectListItem() 
    { 
        Text = x != 1949 ? x.ToString() : "Unselected", 
        Value = x != 1949 ? new DateTime(x, 1, 1).ToString() : null,
        Selected = () => 
        {
            if (x == 1949 && !ClientSinceYearOnly.HasValue)
                return true;
            else if (ClientSinceYearOnly.Value == x)
                return true;
            else
                return false;
        }
    }));

Я хочу, чтобы значение Selected было результатом выражения labmda, которое определено встроенным.Я знаю, что могу сделать это, назначив лямбду переменной, а затем вызвав ее, но я думаю, что определение и немедленное обращение к ней «чище».

Ответы [ 4 ]

7 голосов
/ 17 марта 2012

Прежде всего, чтобы действительно ответить на ваш вопрос: вы можете вызвать лямбду «на месте», передав ее делегату:

bool x = ((Func<bool>) ()=>true) ();

Но в вашем коде нет необходимости в лямбде впервое место;Я не понимаю, почему у вас есть лямбда вообще.Вы хотите вычислить логическое значение, поэтому вычислите логическое значение :

Selected = (x == 1949 && !ClientSinceYearOnly.HasValue) || 
                         (ClientSinceYearOnly.Value == x)

(Также обратите внимание, что вам не нужно проверять, имеет ли значение, допускающее обнуляемое значение, перед тем, как сравнивать; равенство "поднято до нуля" в C #.)

Во-вторых, этот запрос беспорядок, потому что у вас есть особый случай там.Я бы не стал так писать ваш запрос.Я бы скорее сказал:

var choices = new List<Item>();
choices.Add(new SelectListItem()
{
    Text = "Unselected",
    Value = null;
    Selected = ClientSinceYearsOnly == null
};

choices.AddRange(
    Enumerable.Range(1950, DateTime.Now.Year - 1951)
    .Select(x => new SelectListItem() 
    { 
        Text = x.ToString(), 
        Value = new DateTime(x, 1, 1).ToString(),
        Selected = x == ClientSinceYearOnly
    });

Намного понятнее.Или напишите себе метод расширения, который помещает что-то в начало последовательности:

public static IEnumerable<T> Prepend<T>(this IEnumerable<T> sequence, T first)
{
    yield return first;
    foreach(T item in sequence) 
        yield return item;
}

, а затем:

var choices = 
    Enumerable.Range(1950, DateTime.Now.Year - 1951)
    .Select(x => new SelectListItem() 
    { 
        Text = x.ToString(), 
        Value = new DateTime(x, 1, 1).ToString(),
        Selected = x == ClientSinceYearOnly
    })
    .Prepend(new SelectListItem()
    {
        Text = "Unselected",
        Value = null;
        Selected = ClientSinceYearsOnly == null
    });
4 голосов
/ 17 марта 2012

Вы всегда можете поместить условное выражение в метод и вызвать его:

public static bool ShouldBeSelected(int x)
{
    if (x == 1949 && !ClientSinceYearOnly.HasValue)
        return true;
    else if (ClientSinceYearOnly.Value == x)
        return true;
    else
        return false;
}

Тогда вы можете просто использовать его:

        (clientSinceChoices =  Enumerable.Range(1949, DateTime.Now.Year - 1950)
                                        .Select(x => new SelectListItem() 
                                        { 
                                            Text = x != 1949 ? x.ToString() : "Unselected", 
                                            Value = x != 1949 ? new DateTime(x, 1, 1).ToString() : null,
                                            Selected = ShouldBeSelected(x)
                                        }));
<ч />

Кроме того, в вашем случае вы можете использовать серию логических операторов, поскольку вы возвращаете логическое значение ( не рекомендуется , если вы не хотите, чтобы будущие сопровождающие убивали вас во сне):

(x == 1949 && !ClientSinceYearOnly.HasValue) || (ClientSinceYearOnly.Value == x)
1 голос
/ 17 марта 2012

Это не лучшее использование лямбды, но способ, которым вы вызываете лямбда-инлайн, заключается в том, чтобы поставить после него круглые скобки:

(clientSinceChoices =  Enumerable.Range(1949, DateTime.Now.Year - 1950)
    .Select(x => new SelectListItem() 
    { 
        Text = x != 1949 ? x.ToString() : "Unselected", 
        Value = x != 1949 ? new DateTime(x, 1, 1).ToString() : null,
        Selected = ((Func<bool>)(() => 
        {
            if (x == 1949 && !ClientSinceYearOnly.HasValue)
                return true;
            else if (ClientSinceYearOnly.Value == x)
                return true;
            else
                return false;
        }))() // <-- the () calls the function
    }));
0 голосов
/ 17 марта 2012

Следующий код функционально эквивалентен:

Selected = 
    x == 1949 && !ClientSinceYearOnly.HasValue ||
    ClientSinceYearOnly.Value == x;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...