Как проверить на пустые указатели в глубоком лямбда-выражении? [дубликат]

Я удалил несколько строк, которые мне показались ненужными, но вы можете добавить их обратно, если хотите. Следующий код должен работать так, как вы ожидали

       $(document).ready(function () {
            var item, tile, author, publisher, bookLink, bookImg;
            var outputList = $("#list-output");

            //listener for search button
            $("#search").click(function () {
                var searchData = $("#search-box").val();
                if (searchData === "") {
                    // dsiplayErr();
                } else {
                    console.log(searchData);
                    $.get("https://www.googleapis.com/books/v1/volumes?q=" + searchData, function (response) {
                        for (var i = 0; i < response.items.length; i++) {
                            item = response.items[i];
                            title = item.volumeInfo.title;
                            author = item.volumeInfo.authors;
                            publisher = item.volumeInfo.publisher;
                            bookLink = item.selfLink;
                            bookImg = item.volumeInfo.imageLinks.thumbnail;
                            // in production code, item.text should have the HTML entities escaped.
                            var html;
                            if ((response.items.length % 2 != 0) && (i == response.items.length - 1)) {
                                html = "";
                                html += "<div class='row'>";
                                html += formatOutput(title, author, publisher, bookLink, bookImg);
                                html += "</div>";
                                outputList.append(html);
                            }
                            else {
                                if (i % 2 == 0) {
                                    html = "";
                                    html += "<div class='row'>";
                                }

                                html += formatOutput(title, author, publisher, bookLink, bookImg);

                                if (i % 2 != 0) {
                                    html += "</div>";
                                    outputList.append(html);
                                }
                            }
                        }
                    });
                }
            });

        });



        function formatOutput(title, author, publisher, bookLink, bookImg) {
            // console.log(title + ""+ author +" "+ publisher +" "+ bookLink+" "+ bookImg)
                var htmlCard1 = `<div class="col-lg-6">
                <div class="card" style="">
                  <div class="row no-gutters">
                    <div class="col-md-4">
                      <img src="${bookImg}" class="card-img" alt="...">
                    </div>
                    <div class="col-md-8">
                      <div class="card-body">
                        <h5 class="card-title">${title}</h5>
                        <p class="card-text">Author: ${author}</p>
                        <p class="card-text"><small class="text-muted">Publisher: ${publisher}</small></p>
                        <a href="${bookLink}" class="btn btn-secondary">More Info</a>
                      </div>
                    </div>
                  </div>
                </div>
              </div>`
            return htmlCard1;
        }
14
задан JohnRudolfLewis 12 May 2009 в 21:07
поделиться

8 ответов

Вы не можете сделать это кратко. Вы можете сделать лямбда-выражение несколькими строками или использовать вложенные тернарные операторы:

var result = GetValue(one, x => x.Two == null ? null :
                                x.Two.Three == null ? null :
                                x.Two.Three.Four == null ? null :
                                x.Two.Three.Four.Foo;

Уродливо, я знаю.

13
ответ дан 1 December 2019 в 06:31
поделиться

Вы можете сделать это с помощью универсального вспомогательного метода расширения, например:

public static class Get {
    public static T IfNotNull<T, U>(this U item, Func<U, T> lambda) where U: class {
        if (item == null) {
            return default(T);
        }
        return lambda(item);
    }
}

var one = new One();
string fooIfNotNull = one.IfNotNull(x => x.Two).IfNotNull(x => x.Three).IfNotNull(x => x.Four).IfNotNull(x => x.Foo);
17
ответ дан 1 December 2019 в 06:31
поделиться

Всегда инициализируйте свои свойства перед их использованием. Добавьте конструктор в класс One, Two, Three и Four. В конструкторе инициализируйте свои свойства, чтобы они не были нулевыми.

0
ответ дан 1 December 2019 в 06:31
поделиться

Чтобы сделать это кратко, требуется еще не реализованный оператор. Мы рассмотрели возможность добавления оператора ".?" на C # 4.0, который имел бы желаемую семантику, но, к сожалению, не укладывался в наш бюджет. Мы рассмотрим это в качестве гипотетической будущей версии языка.

7
ответ дан 1 December 2019 в 06:31
поделиться

Я не разбираюсь в C #, но, возможно, есть способ реализовать "andand"

2
ответ дан 1 December 2019 в 06:31
поделиться

Вы можете изменить свои геттеры, чтобы они читались примерно так:

private Two _two;
public Two Two
{
     get 
     {
       if (null == _two)
         return new Two();
       else
         return _two;
      }
}
0
ответ дан 1 December 2019 в 06:31
поделиться

Иногда я считаю, что для этого может быть полезен оператор coalesce. Это помогает только в том случае, если есть версия объекта, эквивалентная по умолчанию / null, которую вы можете добавить.

Например, иногда, когда я открываю XML ...

IEnumeratable<XElement> sample;
sample.Where(S => (S.Attribute["name"] ?? new XAttribute("name","")).Value.StartsWith("Hello"))...

В зависимости от того, как объекты по умолчанию извлекаются, это может быть многословным, и приведенный выше пример не очень полезен, но вы поняли идею. Для частного случая чтения атрибутов XML у меня есть метод расширения, который возвращает значение атрибута или пустую строку.

0
ответ дан 1 December 2019 в 06:31
поделиться

Теперь вы можете использовать проект Maybe на codeplex.

Синтаксис:

string result = One.Maybe(o => o.Two.Three.Four.Foo);

string cityName = Employee.Maybe(e => e.Person.Address.CityName);
4
ответ дан 1 December 2019 в 06:31
поделиться
Другие вопросы по тегам:

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