Расширение C# объединяет оператор

Google Datastore - это база данных NoSQL, которая работает с сущностями, а не с таблицами. Вам нужно загрузить все «записи», которые являются «ключевыми идентификаторами», в Datastore и все их «свойства», то есть «столбцы», которые вы видите в консоли. Но вы хотите загрузить их на основе «доброго» имени, которое является «таблицей», на которую вы ссылаетесь.

Ниже приведено решение о том, как извлечь все идентификаторы ключей и их свойства из хранилища данных с помощью облачной функции HTTP-триггера, работающей в среде Node.js 8.

  1. Создайте облачную функцию Google и выберите триггер для HTTP.
  2. Выберите время выполнения: Node.js 8
  3. В index.js замените весь код на , этот код GitHub .
  4. В package.json добавить:
    {
      "name": "sample-http",
      "version": "0.0.1",
      "dependencies": {
        "@google-cloud/datastore": "^3.1.2"
      }
    }
  1. Под Функция для выполнения добавить loadDataFromDatastore, так как это имя функции, которую мы хотим выполнить.

ПРИМЕЧАНИЕ. При этом все загруженные записи будут записываться в журналы Stackdriver функции Cloud. Ответом для каждой записи является JSON, поэтому вам придется преобразовать ответ в объект JSON, чтобы получить нужные данные. Получите идею и измените код соответствующим образом.

BLOCKQUOTE>

14
задан laktak 24 March 2009 в 20:20
поделиться

7 ответов

Это смутило меня уже... обычно, Вы думаете, объединяют действие на его значения - я предположил что первый непустой указатель (f) => f.Value, и "default value" был бы возвращен, который не имеет место (пустой тест находится на инициирующем экземпляре).

Обратите внимание, что это было бы более ясно без скобок?

f => f.Value

То, что Вы на самом деле делаете, подобно Select - так что-то как SafeSelect было бы хорошее имя, IMO (но возможно не точно это...).

Или даже просто Dereference, пока имя аргумента (и т.д.) проясняет, для чего второй аргумент.

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

Да, я понял бы это. Да, объедините, хорошее имя. Да, было бы лучше, если бы C# имел пустой безопасный оператор разыменования как Groovy и некоторые другие языки :)

Обновление

C# 6 имеет такой оператор - пустой условный оператор, ?. Например:

var street = customer?.PrimaryAddress?.Street;

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

var street = customer?.PrimaryAddress?.Street ?? "(no address given)";

Или, на основе исходного кода в вопросе:

Console.WriteLine(getSomeFoo()?.Value ?? "default"); 

Отмечание, конечно, что, предоставляя значению по умолчанию этот путь работает, только если он должен хорошо использовать то значение по умолчанию, даже когда заключительное значение свойства доступно, но устанавливается в NULL по некоторым причинам.

Результат выражения x?.y null если x оценивает к пустому указателю; иначе это - результат x.y. О, и можно использовать его для условного вызова метода, также:

possiblyNull?.SomeMethod();
11
ответ дан 1 December 2019 в 12:02
поделиться

Это могло легко быть расширено также:

public static TResult Coalesce<T, TResult>(this T obj, Func<T, TResult> func, TResult defaultValue)
{
    if (obj == null)
        return defaultValue;

    return func(obj);
}

public static TResult Coalesce<T1, T2, TResult>(this T1 obj, Func<T1, T2> func1, Func<T2, TResult> func2, TResult defaultValue)
{
    if (obj == null)
        return defaultValue;

    T2 obj2 = func1(obj);
    if (obj2 == null)
        return defaultValue;

    return func2(obj2);
}

public static TResult Coalesce<T1, T2, T3, TResult>(this T1 obj, Func<T1, T2> func1, Func<T2, T3> func2, Func<T3, TResult> func3, TResult defaultValue)
{
    if (obj == null)
        return defaultValue;

    T2 obj2 = func1(obj);
    if (obj2 == null)
        return defaultValue;

    T3 obj3 = func2(obj2);
    if (obj3 == null)
        return defaultValue;

    return func3(obj3);
}

public static TResult Coalesce<T1, T2, T3, T4, TResult>(this T1 obj, Func<T1, T2> func1, Func<T2, T3> func2, Func<T3, T4> func3, Func<T4, TResult> func4, TResult defaultValue)
{
    if (obj == null)
        return defaultValue;

    T2 obj2 = func1(obj);
    if (obj2 == null)
        return defaultValue;

    T3 obj3 = func2(obj2);
    if (obj3 == null)
        return defaultValue;

    T4 obj4 = func3(obj3);
    if (obj4 == null)
        return defaultValue;

    return func4(obj4);
}

Который мог использоваться как это:

BinaryTreeNode node = LocateNode(someKey);
BinaryTreeNode grandFatherNode = node.Coalesce(n1 => n1.Parent, n2 => n2.Parent, null);

Который заменил бы:

BinaryTreeNode grandFatherNode = node.Parent.Parent; // or null if none
3
ответ дан 1 December 2019 в 12:02
поделиться

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

Однако, если только используется 1 или 2 раза, я думаю "в строке", если будет лучше, поскольку я не вижу для размышления о значении, “если” в первый раз я вижу его.

"В строке", если - я имею в виду нормальное, если оператор, который не имеет быть скрытым в отдельном методе.

1
ответ дан 1 December 2019 в 12:02
поделиться

Кажется достаточно читаемым, хотя это все еще немного неуклюже.

Это походит на идеальную возможность реализовать шаблон несуществующего объекта все же.

Рассмотрите:

public class Foo
{
  public Foo(string value) { Value=value; }
  public string Value { get; private set; }
  private static Foo nullFoo = new Foo("default value");
  public static Foo NullFoo { get { return nullFoo; } }
}

Затем имейте getSomeFoo (), возвращают Foo. NullFoo вместо пустого указателя. Это требует небольшой дополнительной мысли, но обычно делает для более хорошего кода.

Обновление в ответ на комментарии:

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

public class NullFoo : Foo
{
    private NullFoo() : base("default value") { }
    private static NullFoo instance = new NullFoo();
    public static Foo Instance { get { return instance; } }
}

Затем возвратите NullFoo. Экземпляр от getSomeFoo (). Если Вы не управляете getSomeFoo () также, у Вас и все же есть опция сделать это:

Console.WriteLine((getSomeFoo() ?? NullFoo.Instance).Value);
2
ответ дан 1 December 2019 в 12:02
поделиться

Почему не записать нормальную функцию Coalesce, то вы могли бы использовать это так:

coalesce(something, something_else, "default");

Другими словами - Что вам нужны лямбдас?

?
0
ответ дан 1 December 2019 в 12:02
поделиться

Отличный пост! Я обновил ваш код, чтобы поддержать возвращение Nullable, потому что NULLABLE реализован как структура.

    public static class Coalesce
    {
        public static TResult UntilNull<T, TResult>(T obj, Func<T, TResult> func) where TResult : class
        {
            if (obj != null) return func(obj);
            else return null;
        }

        public static TResult UntilNull<T1, T2, TResult>(T1 obj, Func<T1, T2> func1, Func<T2, TResult> func2) where TResult : class
        {
            if (obj != null) return UntilNull(func1(obj), func2);
            else return null;
        }

        public static TResult UntilNull<T1, T2, T3, TResult>(T1 obj, Func<T1, T2> func1, Func<T2, T3> func2, Func<T3, TResult> func3) where TResult : class
        {
            if (obj != null) return UntilNull(func1(obj), func2, func3);
            else return null;
        }

        public static TResult UntilNull<T1, T2, T3, T4, TResult>(T1 obj, Func<T1, T2> func1, Func<T2, T3> func2, Func<T3, T4> func3, Func<T4, TResult> func4) where TResult : class
        {
            if (obj != null) return UntilNull(func1(obj), func2, func3, func4);
            else return null;
        }

        public static Nullable<TResult> UntilNull<T, TResult>(T obj, Func<T, Nullable<TResult>> func) where TResult : struct
        {
            if (obj != null) return func(obj);
            else return new Nullable<TResult>();
        }

        public static Nullable<TResult> UntilNull<T1, T2, TResult>(T1 obj, Func<T1, T2> func1, Func<T2, Nullable<TResult>> func2) where TResult : struct
        {
            if (obj != null) return UntilNull(func1(obj), func2);
            else return new Nullable<TResult>();
        }

        public static Nullable<TResult> UntilNull<T1, T2, T3, TResult>(T1 obj, Func<T1, T2> func1, Func<T2, T3> func2, Func<T3, Nullable<TResult>> func3) where TResult : struct
        {
            if (obj != null) return UntilNull(func1(obj), func2, func3);
            else return new Nullable<TResult>();
        }

        public static Nullable<TResult> UntilNull<T1, T2, T3, T4, TResult>(T1 obj, Func<T1, T2> func1, Func<T2, T3> func2, Func<T3, T4> func3, Func<T4, Nullable<TResult>> func4) where TResult : struct
        {
            if (obj != null) return UntilNull(func1(obj), func2, func3, func4);
            else return new Nullable<TResult>();
        }
    }
1
ответ дан 1 December 2019 в 12:02
поделиться
Другие вопросы по тегам:

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