Помогите составить грамотное Linq выражение.
От: Аноним  
Дата: 05.10.10 07:45
Оценка:
допустим есть класс

class MyType
{
    public int ID { get; set; }
}


Нужно произвести поиск элементов в коллекции этих типов, где один из элементов может быть нулем. Из кода я думаю ясно, что я хочу. Выражение Linq в методе Find вызывает NullReference Exception.

private void simpleButton4_Click(object sender, EventArgs e) {
    IEnumerable<MyType> coll = new MyType[] {
        null,    // Внимание null
        new MyType() { ID = 1},
        new MyType() { ID = 2}
    };

    MyType pat1 = null;
    MyType found1 = Find(pat1, coll); // должен вернуть null

    MyType pat2 = new MyType() { ID = 3 };
    MyType found2 = Find(pat2, coll); // должнен вернуть null (NullReference Exception)

    MyType pat3 = new MyType() { ID = 1 };
    MyType found3 = Find(pat3, coll); // должен вернить второй элемент коллекции (NullReference Exception)
}
        
private MyType Find(MyType pattern, IEnumerable<MyType> coll)  {
    return coll.Where(x=> (pattern == null && x == null) || (pattern != null && pattern.ID == x.ID)).FirstOrDefault();
}


PS. На самом деле я создал метод (код не привожу), который правильно решает задачу, просто он получился достаточно сложным для такой простой задачи. Подозреваю можно как-то по-другому с Linq вывернуться
Re: Помогите составить грамотное Linq выражение.
От: Пельмешко Россия blog
Дата: 05.10.10 07:56
Оценка:
Здравствуйте, Аноним, Вы писали:

А>PS. На самом деле я создал метод (код не привожу), который правильно решает задачу, просто он получился достаточно сложным для такой простой задачи. Подозреваю можно как-то по-другому с Linq вывернуться


private MyType Find(MyType pattern, IEnumerable<MyType> coll)
{
    if (pattern == null)
        throw new ArgumentNullException("pattern");

    return coll.FirstOrDefault(x => x != null && pattern.ID == x.ID);
}
Re: Помогите составить грамотное Linq выражение.
От: QrystaL Украина  
Дата: 05.10.10 08:00
Оценка:
        private static MyType Find(MyType pattern, IEnumerable<MyType> coll)
        {
            if (pattern == null)
            {
                return null;
            }

            return coll
                .Where(x => x != null && x.ID == pattern.ID)
                .FirstOrDefault();
        }
Re[2]: Помогите составить грамотное Linq выражение.
От: Аноним  
Дата: 05.10.10 08:24
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>Здравствуйте, Аноним, Вы писали:


А>>PS. На самом деле я создал метод (код не привожу), который правильно решает задачу, просто он получился достаточно сложным для такой простой задачи. Подозреваю можно как-то по-другому с Linq вывернуться


П>
П>private MyType Find(MyType pattern, IEnumerable<MyType> coll)
П>{
П>    if (pattern == null)
П>        throw new ArgumentNullException("pattern");

П>    return coll.FirstOrDefault(x => x != null && pattern.ID == x.ID);
П>}
П>



Блин, слишком упростил свою задачу для примера, только сейчас дошло. Реальный пример выглядит немного иначе. Я сейчас оформлю
Re: Помогите составить грамотное Linq выражение.
От: k.o. Россия  
Дата: 05.10.10 08:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>допустим есть класс


А>
class MyType
А>{
А>    public int ID { get; set; }
А>}


А>Нужно произвести поиск элементов в коллекции этих типов, где один из элементов может быть нулем. Из кода я думаю ясно, что я хочу. Выражение Linq в методе Find вызывает NullReference Exception.


А>
А>private MyType Find(MyType pattern, IEnumerable<MyType> coll)  {
А>    return coll.Where(x=> (pattern == null && x == null) || (pattern != null && x != null && pattern.ID == x.ID)).FirstOrDefault();
А>}
А>


См. выделенное.

На самом деле, учитывая, что MyType это класс, то, в случае, если pattern == null метод Find также будет всегда возвращать null, поэтому можно переписать немного проще:

private MyType Find(MyType pattern, IEnumerable<MyType> coll)  {
    if (pattern == null)
    {
        return null;
    }

    return coll.Where(x=> x != null && pattern.ID == x.ID).FirstOrDefault();
}
Re: Помогите составить грамотное Linq выражение.
От: Аноним  
Дата: 05.10.10 08:33
Оценка:
В моем первом посте я слишком упросил пример, в итоге накосячил. Реальный пример выглядит примерно так (надеюсь из кода все ясно):

private void simpleButton4_Click(object sender, EventArgs e) {
    IEnumerable<DisplayMyType> coll = new DisplayMyType[] {
        new DisplayMyType() { DisplayName = "NULL", MyType = null },
        new DisplayMyType() { DisplayName = "A", MyType = new MyType() { ID = 1} },
        new DisplayMyType() { DisplayName = "B", MyType = new MyType() { ID = 2} },
    };
   

    MyType pat1 = null;
    DisplayMyType found1 = Find(pat1, coll); // должен вернуть первый элемент коллекции

    MyType pat2 = new MyType() { ID = 3 };
    DisplayMyType found2 = Find(pat2, coll); // должнен вернуть null (но NullReference Exception)

    MyType pat3 = new MyType() { ID = 1 };
    DisplayMyType found3 = Find(pat3, coll); // должен вернить второй элемент коллекции (но NullReference Exception)
}

private DisplayMyType Find(MyType pattern, IEnumerable<DisplayMyType> coll) {
    return coll.Where(x=> (pattern == null && x.MyType == null) || (pattern != null && pattern.ID == x.MyType.ID)).FirstOrDefault();
}

class MyType
{
    public int ID { get; set; }
}

class DisplayMyType
{
    public String DisplayName { get; set; }
    public MyType MyType { get; set; } 
}
Re[2]: Помогите составить грамотное Linq выражение.
От: Пельмешко Россия blog
Дата: 05.10.10 08:39
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В моем первом посте я слишком упросил пример, в итоге накосячил. Реальный пример выглядит примерно так (надеюсь из кода все ясно):


private DisplayMyType Find(MyType pattern, IEnumerable<DisplayMyType> coll) {
    return coll.FirstOrDefault(x => (pattern == null) || (x.MyType != null && pattern.ID == x.MyType.ID));
}
Re[2]: Помогите составить грамотное Linq выражение.
От: QrystaL Украина  
Дата: 05.10.10 08:47
Оценка:
        private static DisplayMyType Find(MyType pattern, IEnumerable<DisplayMyType> coll)
        {
            if (pattern == null)
            {
                return coll
                    .Where(e => e.MyType == null)
                    .FirstOrDefault();
            }
            else
            {
                return coll
                    .Where(e => e.MyType != null && e.MyType.ID == pattern.ID)
                    .FirstOrDefault();
            }
        }
Re[3]: Помогите составить грамотное Linq выражение.
От: Аноним  
Дата: 05.10.10 08:57
Оценка:
Здравствуйте, QrystaL, Вы писали:

QL>
QL>        private static DisplayMyType Find(MyType pattern, IEnumerable<DisplayMyType> coll)
QL>        {
QL>            if (pattern == null)
QL>            {
QL>                return coll
QL>                    .Where(e => e.MyType == null)
QL>                    .FirstOrDefault();
QL>            }
QL>            else
QL>            {
QL>                return coll
QL>                    .Where(e => e.MyType != null && e.MyType.ID == pattern.ID)
QL>                    .FirstOrDefault();
QL>            }
QL>        }
QL>


Должен сказать, один в один с моим собственным неопубликованным вариантом. Спасибо
Re[2]: Помогите составить грамотное Linq выражение.
От: k.o. Россия  
Дата: 05.10.10 09:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В моем первом посте я слишком упросил пример, в итоге накосячил. Реальный пример выглядит примерно так (надеюсь из кода все ясно):


private DisplayMyType Find(MyType pattern, IEnumerable<DisplayMyType> coll) {
    return coll.Where(x=> (pattern == x.MyType) || (pattern != null && x.MyType != null && pattern.ID == x.MyType.ID)).FirstOrDefault();
}
Re[3]: Помогите составить грамотное Linq выражение.
От: Аноним  
Дата: 05.10.10 09:03
Оценка:
П>
П>private DisplayMyType Find(MyType pattern, IEnumerable<DisplayMyType> coll) {
П>    return coll.FirstOrDefault(x => (pattern == null) || (x.MyType != null && pattern.ID == x.MyType.ID));
П>}
П>



Перестановка элементов в коллекции:
IEnumerable<DisplayMyType> coll = new DisplayMyType[] {
new DisplayMyType() { DisplayName = "A", MyType = new MyType() { ID = 1} },
new DisplayMyType() { DisplayName = "B", MyType = new MyType() { ID = 2} },
new DisplayMyType() { DisplayName = "NULL", MyType = null }
};
и уже это "(pattern == null)" не работает
Re[4]: Помогите составить грамотное Linq выражение.
От: QrystaL Украина  
Дата: 05.10.10 09:04
Оценка:
А>Должен сказать, один в один с моим собственным неопубликованным вариантом. Спасибо

В данном случае читабельность будет выше, если разбить на 2 запроса. Так что все логично )
Re[3]: Помогите составить грамотное Linq выражение.
От: Аноним  
Дата: 05.10.10 09:08
Оценка:
KO>
KO>private DisplayMyType Find(MyType pattern, IEnumerable<DisplayMyType> coll) {
KO>    return coll.Where(x=> (pattern == x.MyType) || (pattern != null && x.MyType != null && pattern.ID == x.MyType.ID)).FirstOrDefault();
KO>}
KO>


вот это работает. Спасибо
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.