2009-10-29 3 views
1
Func<Classification, string> test1 = c => c.Id = "x"; 
Func<Classification, string> test2 = c => { return c.Id = "x";}; 

J'ai travaillé avec lambda de près d'un an ou maintenant et assez raisonnable avec eux, mais aujourd'hui, je regardais NBuilder et vu un Func bizarre qui ne semble pas correspondre aux exemples . J'ai joué de toute façon et ça se vérifie mais je ne comprends pas pourquoi les compilations ci-dessus et encore moins les runs. Nous faisons une mission et donc l'expression n'évalue rien, n'est-ce pas ??? ou nonC# Lambda comportement déconcertant

donc je pensais que peut-être quelque chose que j'ai manqué lié à lambda, donc j'ai essayé quelque chose d'autre:

[Test] 
    public void AmIGoingMad() 
    { 
     Assert.That(Test(),Is.Null); // not sure what to expect - compile fail? 
    } 

    public string Test() 
    { 
     string subject = ""; 
     return subject = "Matt"; 
    } 

Effectivement AmIGoingMad échoue et « Matt » est en fait retourné.

Pourquoi avons-nous ce comportement? Où est-ce documenté? Est-ce purement un raccourci syntaxique? J'ai l'impression d'avoir manqué quelque chose de fondamental dans ma compréhension de lambda ou même de C#.

Se sentir bête.

+0

sujet == "Matt"? –

+0

Oh, ça fait des années que je fais ça ... Je n'ai jamais pensé ... Je serais damné. IPerson personne = null; if ((par exemple en tant que personne)! = Null) {} –

+0

Je pense que vous devez clarifier. "Où est-ce documenté?" <- qu'est ce que "ceci" dans cette phrase? "Est-ce purement ..." - encore une fois, qu'est-ce que "ça"? "ce comportement", quel comportement? Cette déclaration renvoie une valeur? Cela = affecte une valeur? Que "Matt" n'est pas nul? –

Répondre

9

Une instruction d'affectation a une valeur de retour - cette valeur est celle qui a été affectée. Même C avait cela, vous pouvez donc enchaîner des missions telles que les suivantes:

a = b = c = d = 10; 

L'affectation à d a la valeur de rendement de 10 qui obtient affecté à c, et ainsi de suite.

1

Ce que vous voyez est le chaînage d'affectation, quelque chose qui remonte à C/C++. Il est là pour soutenir ce scénario:

int a = b = c = 0; 

Ou quelque part je l'utilise réellement:

public static IEnumerable<string> ReadLines(string filePath) 
{ 
    using (var rdr = new StreamReader(filePath)) 
    { 
     string line; 
     while ((line = rdr.ReadLine()) != null) // <----- 
     { 
      yield return line; 
     } 
    } 
} 
0

Je ne comprends pas votre question.

Vous postez le code qui vous ressemble avez mal compris la différence entre = et ==, puis commenter explicitement que vous voulez utiliser = qui est l'opérateur d'affectation.

Permettez-moi de vous poser une question à la place:

Pourquoi voudriez-vous ou attendre que cela ne compilera pas?

Assert.That(Test(),Is.Null); // not sure what to expect - compile fail? 

Fondamentalement, vous faites ceci:

String temp = Test(); 
Assert.That(temp, Is.Null); 
1

Cela fonctionne parce que l'affectation c.Id = "x" évalue à la valeur de "x". Vous pouvez utiliser ceci par exemple si vous voulez assigner et vérifier une valeur dans une instruction (que certains considèrent comme une mauvaise pratique) comme ceci:

string s; 
if((s = SomeFunction()) != null) { \\do something with s } 
1

Comme d'autres ont dit, l'affectation retourne une valeur elle-même.

Vous pouvez également profiter comme ceci:

private List<string> theList; 
public List<string> LazyList 
{ 
    get { return theList ?? (theList = new List<string>()); } 
} 
+0

Cela brise l'hypothèse de pureté des getters de propriété (pas d'effets secondaires). –

+0

@ 280Z28 - Ceci est un exemple valide d'une propriété de chargement paresseux. En .Net4, ils ont ajouté Lazy <> pour rendre facilement ce type de propriété threadsafe. – Pedro