2016-03-19 2 views
-2

Недавно я столкнулся с проблемой, которая заняла некоторое время, чтобы понять. У меня есть такой кусок кода:По умолчаниюIfEmpty особенности поведения

private Member FindMemberByName(string name) 
{ 
    var member = 
     this.db.Members.AsEnumerable() 
     .Where(d => d.ShortName == name) 
     .DefaultIfEmpty(this.CreateNewMember(name)) 
     .First(); 
    return member; 
} 

private Member CreateNewMember(string name) 
{ 
    return this.db.Members.Add(new Member { Name = name }); 
} 

Я ожидал FindMemberByName() для возврата существующего объекта, а в случае отсутствия создать новый объект и вернуть один.

Однако я заметил, что CreateNewMember() был вызван даже тогда, когда существующее имя было передано.

+2

Я предпочел бы использовать шаблон 'FirstOrDefault() ?? CreateNewMember', который представляет собой микроразделение проблем. –

ответ

1

После небольшой отладки я понял, что значение параметра DefaultIfEmpty() оценивается немедленно, даже если не вызывается метод First(). Поэтому на самом деле это оценивается, прежде чем понимать, является ли результирующий IEnumerable пустым или нет.

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

+8

Измените свой ответ и ответьте на него. (Ответы на автоответчики в порядке, но их следует делать в правильном формате вопрос/ответ). –

3

Поведение, о котором вы просите, не имеет ничего общего с LINQ. Метод, который вы размещаете в списке параметров DefaultIfEmpty(), будет оцениваться до того, как будет вызван DefaultIfEmpty(). Вы можете увидеть это, закодировав аналогичный метод, который не ссылается на объект по умолчанию.

void Main() 
{ 
    CalledMethod(CreateDefault("Hello World")); 
} 

void CalledMethod<TSource>(TSource defaultValue) 
{ 
} 

TestClass CreateDefault(string message) 
{ 
    return new TestClass() { Message = message, }; 
} 

public class TestClass 
{ 
    public string Message { get; set; } = null; 
    public TestClass() { } 
} 
Смежные вопросы