Перепутанный параметрами LINQ

Работа с Observables является асинхронной, поэтому в вашем примере это «возврат данных»; строка будет выполнена задолго до того, как «data = doc.payload.doc.get (« привилегии »);» выполняется.

Если метод getUserPrivilegeByUserId () находится в компоненте , подход к решению этой проблемы будет заключаться в том, чтобы установить данные как свойство компонента, а затем обновить их в подписке, например: ]

  data: string;

  ...

  getUserPrivilegeByUserId(uid:string){
    this.db.collection('users', ref => { return ref.where('uid','==',uid)}).snapshotChanges().subscribe(result => {  
      result.forEach(doc =>{
        this.data = doc.payload.doc.get("privileges");
      })
     }
    );
  }

Если, с другой стороны, метод getUserPrivilegeByUserId () живет в службе , вы можете вернуть Observable из службы следующим образом:

  import { map } from 'rxjs/operators';

  ...

  getUserPrivilegeByUserId(uid:string): Observable<string>{
    return this.db.collection('users', ref => { return ref.where('uid','==',uid)}).snapshotChanges()
      .pipe(
        map(result => {  
          var data;
          result.forEach(doc =>{
            data = doc.payload.doc.get("privileges");
          });
          return data;
         })
      );

в вашем компоненте вы будете делать что-то вроде:

  data: string;

  ...

  this.userService.getUserPrivilegeByUserId(uid).subscribe(data => this.data = data);
5
задан Jay Bazuzi 10 March 2009 в 23:38
поделиться

5 ответов

a => a.Length

Я понимаю, что синтаксис, но как это связано с тем, что просит intellisense?

Этот блок кода является лямбда-выражением. Лямбда-выражение является удобным способом генерировать Анонимный метод (в этом случае) или Систему. Linq. Выражения. Выражение. Давайте сломаем его частями.

  • Самая значимая функция =>, который разделяет параметры от тела метода.
  • На левой стороне =>, существует символ: a. Это - объявление параметра для нашего анонимного метода. Компилятор знает, что мы называем OrderBy (), и что OrderBy требует a Func<string, object>. Параметр для такой функции является строкой, таким образом, компилятор решает, что необходимость - строка. Единственной вещью, которую должен был обеспечить программист, является имя.
  • На правой стороне =>, существует тело метода. Так как это - острота, ключевое слово возврата подразумевается. IDE обеспечивает intellisense против как строка, которая позволяет Вам использовать свойство Length.

Теперь, рассмотрите этот C# 2.0...

IEnumerable<string> sortedWords = 
  Enumerable.OrderBy(words, delegate(string a) {return a.Length;});

С C# 3.0

IEnumerable<string> sortedWords = words
  .OrderBy(a => a.Length);
5
ответ дан 13 December 2019 в 05:43
поделиться

Я думаю, что IntelliSense на самом деле довольно полезен, специально для общих методов, которые берут Func<..> введите как аргумент, потому что Вы видите, что типы и типы ведут Вас для понимания то, что мог бы сделать метод.

Например, аргументы в пользу OrderBy IEnumerable<string> как 'этот' аргумент, что означает, что у нас есть некоторый вход, содержащий набор строк. Первый аргумент keySelector имеет тип Func<string, TKey>, что означает, что это - некоторое лямбда-выражение, Вы обеспечиваете, что указывает, как добраться TKey от string.

Это уже предполагает, что метод, вероятно, перечислит по всем объектам (строки) в наборе, и он может использовать keySelector получить значение типа TKey от каждого элемента в наборе. Имя TKey уже предполагает, что это будет использовать это значение для сравнения элементов (строки) с помощью этого расчетного ключа. Однако, если Вы смотрите на другую перегрузку, которая берет IComparer<TKey> затем можно ли быть уверены в этом - этот аргумент указывает больше деталей о том, как Вы хотите сравнить два значения типа TKey, таким образом, функция должна сравнить элементы с помощью этого ключа.

... этот вид размышления о типах занимает время для привыкания к, но после того как Вы изучите это, это может быть чрезвычайно полезно. Это более полезно в "функциональном" стиле кода, который часто использует много дженериков и lamdba выражений в C# 3.0 (и подобные вещи на функциональных языках как F# или другие)

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

Тип (как отображено Intellisense) имеет смысл, если Вы понимаете природу лямбда-выражений в.NET/C#. Иначе это может действительно казаться немного странным для вновь прибывшего. Начните путем полагания, что тип keySelector, Func <TSource, TKey> является просто делегатом. Перед C# 3.0 Вы назвали бы такой метод путем передачи делегата в качестве параметра, например:

IEnumerable<string> sortedWords = words.OrderBy(new Func<string, int>(mySelectorMethod));

где mySelectorMethod является названием обычного метода, который берет строку в качестве параметра и возвращает интервал (Как точка стороны, я предполагаю, что Вы могли использовать анонимных делегатов, но давайте не идти туда на данный момент.) Кроме того, обратите внимание, что этот пример чисто иллюстративен, поскольку LINQ почти всегда используется с.NET 3.5/C# 3.0 (хотя я полагаю, что это может использоваться с любой/и.NET 2.0/C# 2.0 - кто-то исправляет меня, если я неправ). Начиная с C# 3.0 методы могут быть определены встроенные как лямбда-выражения, которые предназначаются, чтобы использоваться при точно таких обстоятельствах как они. Перечитанный по статье MSDN о лямбда-выражениях (связанный выше), если Вы хотите получить надлежащее введение, но здесь я просто опишу использование в этом определенном контексте. Как Вы заявляете, Ваш код (в C# 3.0) является чем-то как следующее:

var sortedWords = words.OrderBy(a => a.Length);

Часть выражения, которое является a => a.Length лямбда-выражение, которое является действительно просто сокращением от объявления встроенной функции. Синтаксис лямбда-выражений довольно прост по большей части; слева от => аргументы указаны, обычно в форме (arg1, arg2, arg3), но так как существует только один в этом случае, можно опустить скобки. Направо от => выражение, которое является возвращаемым значением функции (лямбда-выражение более точно). Кроме того, можно включить фактический код с оператором возврата в {и} хотя это является обычно ненужным. То, что я полагаю, что компилятор C# делает, распознает, что параметр передал OrderBy как лямбда-выражение и затем компилирует его в функцию и создает и передает делегата к Вам. Обратите внимание, что лямбда-выражения могут также быть преобразованы в Систему. Linq. Выражения. Объекты выражения (доступные деревья выражений) вместо делегатов, но это - намного менее общее использование. Так или иначе существует большое продолжение негласно здесь, но надо надеяться это должно, по крайней мере, разъяснить, почему типом является Func <TSource, TKey> и как это касается лямбда-выражения. Как я сказал, читайте на MSDN, если Вы хотите более глубокое понимание LINQ/lambdas/delegates...

6
ответ дан 13 December 2019 в 05:43
поделиться

Я никогда действительно волнуюсь о Intellisense, чтобы быть честным. Это портило меня рано в моем Linqage. Когда я провел больше времени с дженериками и выражениями, оно начало иметь смысл, но до тех пор я просто накачал в синтаксисе.

То, что это хочет, является лямбда-выражением, которое говорит Linq, что искать для сортировки набора.

Я чувствую Вас, моего брата, зависаю там, и это будет иметь смысл очень скоро.

0
ответ дан 13 December 2019 в 05:43
поделиться

OrderBy() берет делегата к функции, которая принимает единственный параметр (в Вашем случае, a string) и возвращает значение типа, который заменяют TKey. Может случиться так, что тип параметра (строка) был уже определен, так как Вы обратились к методу IEnumerable<string> но тип делегата будет только разрешен как Func<string, int> после того, как это выведет его из лямбда-выражения, когда это полностью указано (т.е. a => a.Length). Если Вы не дали синтаксическому анализатору ключа к разгадке относительно того, что Вы хотите как ключ сортировки, он просто покажет TKey в IntelliSense, пока он не сможет определить намеченный тип.

0
ответ дан 13 December 2019 в 05:43
поделиться
Другие вопросы по тегам:

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