Du bist nicht angemeldet.

Werbeanzeige

1

23.11.2018, 23:49

C# Verstehe folgenden Code nicht

C#-Quelltext

1
if(purchases?.Any(p => p.ProductId == productId) ?? false)

Ich weiss dass man diese Zeile braucht um herauszufinden ob sich der gleiche string wie productID auch in purchases befindet, falls dies der Fall ist wird der nachfolgende Code(return true) ausgeführt. Jedoch weiss ich das nur weil ich es mit dem Debugger rausgefunden habe. Ich habe keine Ahnung warum man "purchases?.Any", "p => p.ProductId" und zum Schluss "?? false" schreibt ?(
Kann mir jemand den Code genau erklären?
Ist es möglich die Zeile "if (purchases?.Any(p => p.ProductId == productId) ?? false)" irgendwie anders zu schreiben? Ich habe versucht daraus eine for-Schleife zu machen, jedoch funktioniert das nicht.

Quellcode

1
2
3
4
5
6
7
8
9
10
  //check purchases
  var purchases = await billing.GetPurchasesAsync(ItemType.InAppPurchase);
  int AnzahlPurchases = purchases.Count();
  for (int i = 0; i <= AnzahlPurchases - 1; i++)
  {
    if (purchases[0] == productId)
    //...
    else
    //...
  }

Den Code habe ich aus diesem Artikel: https://jamesmontemagno.github.io/InAppB…ePurchases.html

Tris

Frischling

Beiträge: 29

Wohnort: Nähe Stuttgart

Beruf: neu kompilierter Fachinformatiker Anwendungsentwickler

  • Private Nachricht senden

2

24.11.2018, 03:28

C#-Quelltext

1
if(purchases?.Any(p => p.ProductId == productId) ?? false)

Ich weiss dass man diese Zeile braucht um herauszufinden ob sich der gleiche string wie productID auch in purchases befindet, falls dies der Fall ist wird der nachfolgende Code(return true) ausgeführt. Jedoch weiss ich das nur weil ich es mit dem Debugger rausgefunden habe. Ich habe keine Ahnung warum man "purchases?.Any", "p => p.ProductId" und zum Schluss "?? false" schreibt ?(
Kann mir jemand den Code genau erklären?
Ist es möglich die Zeile "if (purchases?.Any(p => p.ProductId == productId) ?? false)" irgendwie anders zu schreiben? Ich habe versucht daraus eine for-Schleife zu machen, jedoch funktioniert das nicht.

Quellcode

1
2
3
4
5
6
7
8
9
10
  //check purchases
  var purchases = await billing.GetPurchasesAsync(ItemType.InAppPurchase);
  int AnzahlPurchases = purchases.Count();
  for (int i = 0; i <= AnzahlPurchases - 1; i++)
  {
    if (purchases[0] == productId)
    //...
    else
    //...
  }

Den Code habe ich aus diesem Artikel: https://jamesmontemagno.github.io/InAppB…ePurchases.html


Du vergleichst anstelle der Eigenschaft das ganze Objekt mit dem productId String.
Und dann fragst du innerhalb der Schleife jedes Mal nach dem 0 Array Eintrag und nicht nach dem der dem aktuellen Schleifenzähler entspricht.
Probier es mal so:

C#-Quelltext

1
2
3
4
5
6
7
8
9
  //check purchases
  var purchases = await billing.GetPurchasesAsync(ItemType.InAppPurchase);
  for (int i = 0; i < purchases.Count(); i++)
  {
    if (purchases[i].ProductId == productId)
    //...
    else
    //...
  }




C#-Quelltext

1
if (purchases?.Any(p => p.ProductId == productId) ?? false)


Das ?. überprüft erst ob purchases null ist bevor ein Memberzugriff statt findet. Und die ?? geben den linken Wert (in diesem Fall bei einer Übereinstimmung true zurück) wenn dieser nicht null ist ansonsten den Wert rechts davon, also false.

Das musste ich mir auch erstmal angucken. :huh:

https://docs.microsoft.com/de-de/dotnet/…ional-operators

https://docs.microsoft.com/en-us/dotnet/…escing-operator

3

24.11.2018, 08:47

Habs jetzt verstanden, außer diesen Teil noch nicht:

C#-Quelltext

1
p => p.ProductId

Was bedeutet das?

Das mit der for-Schleife funktioniert so nicht:

C#-Quelltext

1
if (purchases[i].ProductId == productId)

Error CS0021: Cannot apply indexing with [] to an expression of type 'IEnumerable<InAppBillingPurchase>'

Wie geht man am besten vor wenn man mehrere productIds kontrollieren möchte?
Das hier wäre ja zu aufwändig wenn man viele productIds hätte:

C#-Quelltext

1
2
3
4
5
6
if(purchases?.Any(p => p.ProductId == productId1) ?? false)
...
if(purchases?.Any(p => p.ProductId == productId2) ?? false)
...
if(purchases?.Any(p => p.ProductId == productId3) ?? false)
...

Deshalb dachte ich an eine for-Schleife um das Problem zu lösen. Oder geht es auch ohne for-Schleife wenn man z.B. 10 verschiedene productIds hätte und die mit purchases vergleichen müsste?

LInsoDeTeh

Treue Seele

Beiträge: 370

Wohnort: Essen, Deutschland

Beruf: Softwareentwickler & Projektleiter

  • Private Nachricht senden

4

24.11.2018, 08:53

Habs jetzt verstanden, außer diesen Teil noch nicht:

C#-Quelltext

1
p => p.ProductId

Was bedeutet das?

Das ist ein Lambda-Ausdruck und eine Kurzschreibweise für:

C#-Quelltext

1
function(Product p) { return p.ProductId; }


PS: Auch wenn in fast allen Beispielen im Netz Lambda-Ausdrücke immer mit nur einem Buchstaben als Variablennamen zu finden sind, kannst du den Namen frei wählen. Ich bevorzuge auch in Lambda-Ausdrücken sprechende Variablennamen, wie sonst überall auch. In deinem Beispiel also:

C#-Quelltext

1
products.Any(product => product.ProductId == productId)


Das macht es einfacher, wenn man z.B. LINQ-Ausdrücke verkettet oder Lambda-Ausdrücke mit mehreren Variablen oder komplexeren Objekten verwendet (was schnell geht, wenn man GroupBy und Select wild kombibiert).

5

24.11.2018, 10:56

Danke :) Lambda-Ausdrücke kannte ich noch nicht.
Das mit der for-Schleife für mehrere ProductIds habe ich jetzt so gelöst:

C#-Quelltext

1
2
3
4
5
6
7
8
List<string> ProductIdListe = new List<string>();
                    for (int i = 0; i <= ProductIdListe.Count() - 1; i++)
                    {
                        if (purchases?.Any(p => p.ProductId == ProductIdListe[i]) ?? false)
                        {                       
                           ...
                        }
                    }

6

24.11.2018, 21:01

Hi, wenn du eh über die komplette Liste iterieren willst, dann nimm lieber foreach. Das ist weniger fehleranfällig

Quellcode

1
2
3
4
5
6
7
8
var ProductIdListe = new List<string>();
foreach(var productId in ProductIdListe)
{
    if (purchases?.Any(p => p.ProductId == productId ) ?? false)
    {                       
       ...
    }   
}



Zusätzlich würde ich vorschlagen den Ausdruck in eine Methode auszulagern Das macht den Code deutlich lesbarer

Quellcode

1
2
3
4
5
6
7
8
9
10
11
foreach(var productId in ProductIdListe)
{
    if (ProductIsPurchased(productId))
    {                       
       ...
    }   
}

....

bool ProductIsPurchased(string productId) => purchases?.Any(p => p.ProductId == productId) ?? false;



Und noch einen Nachtrag. Verwende nur eine Sprache in deinem Code. ProductIdListe ist ein ganz furchtbarer Name, da zwei Sprachen drin sind. Am Besten ist Englisch, weil der Rest vom Code ja auch in Englisch ist. Du wirst sehen, dass macht das echt übersichtlicher.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »fantasielos« (26.11.2018, 22:39)


Werbeanzeige