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

Могу ли я объявить/использовать некоторую переменную в LINQ? Или я могу написать следующий очиститель LINQ?

Можно ли объявить/использовать переменную в LINQ?

Например, можно ли написать следующий очиститель LINQ?

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        where (t.ComponentType.GetProperty(t.Name) != null)
        select t.ComponentType.GetProperty(t.Name);

Существуют ли способы не писать/вызывать t.ComponentType.GetProperty(t.Name) два раза здесь?

4b9b3361

Ответ 1

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        let u = t.ComponentType.GetProperty(t.Name)
        where (u != null)
        select u;

Ответ 2

Вам нужно let:

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        let name = t.ComponentType.GetProperty(t.Name)
        where (name != null)
        select name;

Если вы хотите сделать это в синтаксисе запроса, вы можете сделать это более эффективным (afaik) и более чистым способом:

var q = TypeDescriptor
            .GetProperties(instance)
            .Select(t => t.ComponentType.GetProperty(t.Name))
            .Where(name => name != null);

Ответ 3

Да, используя ключевое слово let:

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
    let nameProperty = t.ComponentType.GetProperty(t.Name)
    where (nameProperty != null)
    select nameProperty;

Ответ 4

Существует альтернатива, о которой мало кто знает (select a into b):

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        select t.ComponentType.GetProperty(t.Name) into u
        where u != null
        select u;

Это означает:

var q = TypeDescriptor.GetProperties(instance)
        .Select(t => t.ComponentType.GetProperty(t.Name))
        .Where(prop => prop != null);

В то время как версия на основе let преобразуется в:

var q = TypeDescriptor.GetProperties(instance)
        .Select(t => new { t, prop = t.ComponentType.GetProperty(t.Name) })
        .Where(x => x.prop != null)
        .Select(x => x.prop);

Необязательное выделение на элемент, поскольку t по-прежнему находится в области видимости (пока не используется). Компилятор С# должен просто оптимизировать это, но это не так (или спецификация языка не позволяет, не уверен).