Laden...

Lambda Kalkül - "??"- Syntax --> Ist kein Lambda, sondern C#

Erstellt von Blaster vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.802 Views
B
Blaster Themenstarter:in
66 Beiträge seit 2013
vor 8 Jahren
Lambda Kalkül - "??"- Syntax --> Ist kein Lambda, sondern C#

Hallo!

Kann mit einer erklären was die "??" Syntax (Semantik) im folgenden Code bedeutet? Die ist leider auch extrem "googlen"-restistent. Ich habe sowas noch nie gesehen.

t.GetProperties().Where(p => 
    (p.GetGetMethod() ?? p.GetSetMethod()).IsDefined(typeof(CompilerGeneratedAttribute), false))
   .Select(p => new 
   { 
      Property = p, 
      Field = t.GetField(string.Format("<{0}>k__BackingField", p.Name),
          System.Reflection.BindingFlags.NonPublic | 
          System.Reflection.BindingFlags.Instance) 
   });

http://stackoverflow.com/questions/2675975/reflection-get-fieldinfo-from-propertyinfo

Danke.
Grüße
Blaster

F
10.010 Beiträge seit 2004
vor 8 Jahren

Das hat überhaupt nichts mit LinQ oder Lambdas zu tun.
https://msdn.microsoft.com/de-de/library/ms173224.aspx

Der operator schaut lediglich ob links von ihm ein NULL Value ist, dann wird die rechte Seite ausgeführt.
In deinem Fall wird also geschaut ob eine GetMethode vorhanden ist, wenn nicht wird der andere Teil ausgeführt.

2.207 Beiträge seit 2011
vor 8 Jahren

Hallo Blaster,

in den Klammern steht ja nix andres als

(p.GetGetMethod() ?? p.GetSetMethod())

was nichts andres heisst als

var anything = (p.GetGetMethod() ?? p.GetSetMethod())

((p => (anything).IsDefined(typeof(CompilerGeneratedAttribute), false)))

den ersten Ausdruck kann man jetzt auch ausschreiben:

var anything = (p.GetGetMethod() ?? p.GetSetMethod())

als


if( p.GetGetMethod() != null )
{
    anything = p.GetGetMethod();
}
else
{
    anything = p.GetSetMethod();
}

Aber googlen nach "Two question mark syntax C#" sollte schon was bringen 😉

Gruss

Coffeebean

EDIT: Zu spät...

B
Blaster Themenstarter:in
66 Beiträge seit 2013
vor 8 Jahren

Hallo!

Super. Danke. 👍
Wo ist den der Unterschied zum ?-Operator z.B. in C++?
Wie {bedingung}?{wahrausführung}:{falschausführung}?
??-hatte ich noch nie gesehen.

Grüße
Blaster

3.003 Beiträge seit 2006
vor 8 Jahren

Der bedingte Operator ? existiert exakt so auch in C#.


int a  = (b < c) ? b : c;
//exakt dasselbe:
int a;
if(b < c) a = b;
else a = c;

Dagegen prüft ?? nur auf null, ist also ein ganz anderer Operator:


string a = b ?? c;
//exakt dasselbe:
if(b == null) a = c;
else a = b;
//exakt dasselbe:
a = (b == null) ? c : b;

Zusätzlich gibts noch .?:


//sei a ein string, von dem wir nicht wissen, ob er null ist
bool condition = a?.Contains("hello, world");
//exakt dasselbe wie:
bool condition;
if(a != null) condition = a.Contains()

Aber ein bisschen C#-Grundlagen kannst du dir besser mit einem Buch erarbeiten, bevor wir hier ein Tutorial draus machen 😉

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

B
88 Beiträge seit 2016
vor 8 Jahren

Aber das => ist schon Lambda oder?

2.207 Beiträge seit 2011
vor 8 Jahren

Hallo Buchstabensuppe,

Operator => (C#-Referenz)

Das =>-Token wird als Operator Lambda bezeichnet.

[Hinweis] Bitte schau in die SDK-/MSDN-Doku

Der Titel bezieht sich auf die "??"-Syntax.

Gruss

Coffeebean

B
88 Beiträge seit 2016
vor 8 Jahren

Danke

2.080 Beiträge seit 2012
vor 8 Jahren

Ergänzend zu den beiden Operatoren ?? und ?., weil es bisher noch nicht hervor kam:
Der Ausdruck auf der linken Seite wird nach der Ausführung immer in eine lokale Variable gelegt, mit der dann weiter gearbeitet wird.

Als Beispiele:

MyObject data = GetFromDatabase() ?? GetDefault();

wird zu:

MyObject data;
MyObject helpVariable = GetFromDatabase();
if (helpVariable == null)
    data = GetDefault();
else
    data = helpVariable;

Und:

MyObject data = GetFromDatabase()?.DoSomething();

wird zu:

MyObject data;
MyObject helpVariable = GetFromDatabase();
if (helpVariable != null)
    data = helpVariable.DoSomething();
else
    data = null;

Wobei das im Detail nicht 100% stimmt. Wenn ich mit den IL-Code anschaue, wird dort dubliziert (dup-Befehl), aber ich denke, dass das je nach Typ unterschiedlich sein kann.

Das Punkt ist aber: Nichts wird ohne das Wissen des Entwicklers zwei mal ausgeführt.

Außerdem ist das bei Events ganz praktisch.
Wenn vor C#6 das nötig war:

var propertyChanged = PropertyChanged;
if (propertyChanged != null)
    propertyChanged(this, eventArgs);

reicht jetzt das:

PropertyChanged?.Invoke(this, eventArgs);

Vorher musste der EventHandler in eine lokale Variable gelegt werden, damit das ganze threadsave ist, das übernimmt bei der neuen Variante der Compiler.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

B
Blaster Themenstarter:in
66 Beiträge seit 2013
vor 8 Jahren

Hallo!

Danke. - Aber offen gesprochen ich kann die Existenzbereichtigung der Extrawust immer noch nicht sehen.
Ich glaube, es ist auch nicht weise weiter zu fragen.

Edit: Palladin007 hat es aber doch beantwortet. (gleichzeitiges Posting)! 👍

Grüße
Blaster

2.080 Beiträge seit 2012
vor 8 Jahren

Joa, ist schon eine Extrawurst 😄
Es hat keine besondere Notwendigkeit, aber es macht den Code teilweise deutlich einfacher und übersichtlicher.

Ich hab manchmal sogar solche Zeilen:

if (GetObject()?.DoSomething()?.DoSomethingElse()?.Bla() ?? false)
    Irgendwas();

Jetzt überleg mal wie aufwendig das wäre, wenn es diese beiden Operatoren nicht gäbe 😄
Und vor allem wie unübersichtlich

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

W
955 Beiträge seit 2010
vor 8 Jahren
if (GetObject()?.DoSomething()?.DoSomethingElse()?.Bla() ?? false)  
    Irgendwas();  

Wobei das schon als Verletzung des Gesetzes von Demeter angesehen werden kann.

2.080 Beiträge seit 2012
vor 8 Jahren

Das stimmt - ich bin aber auch nicht der größte Fan davon 😄

Ich verstehe den Sinn dahinter und das ist durchaus eine kluge Denkweise, allerdings eher selten wirklich so möglich - zumindest nicht ohne die Software an anderen Stellen komplexer oder unübersichtlicher zu gestalten.

Ist denke ich Geschmackssache und ich mag's nicht 😄

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.