2017-08-14 1 views
0

Warum funktioniert das Returns((string food) => eat(food)) während dies nicht funktioniert: Returns(food => eat(food))?Warum benötigt Moq manchmal explizite Typdeklaration in Rückgabe?

Vollarbeitsbeispiel:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var animal = new Mock<IAnimal>(); 
     Func<string, string> eat = food => $"Nom nom nom {food}"; 

     // works 
     animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(eat); 

     // works 
     animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food)); 

     //cannot convert lambda expression to type 'string' because it is not a delegate type 
     animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => eat(food)); 

     //cannot convert lambda expression to type 'string' because it is not a delegate type 
     animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => $"Nom nom nom {food}"); 
    } 
} 

public interface IAnimal 
{ 
    string Eat(string food); 
} 
+1

Es ist nicht Moq, die dies erfordert, es ist der C# -Compiler. Es ist wahrscheinlich, dass die große Anzahl von Überladungen der '.Returns'-Methode (18 bei meiner Zählung) dem Compiler zu viele Optionen gibt. Wenn Code in Zukunft nicht funktioniert (wie in, kompiliert nicht), dann postet bitte die eigentliche Fehlermeldung. In diesem Fall ist es "Kann Lambda-Ausdruck nicht in den Typ 'string' konvertieren, da es sich nicht um einen Delegattyp handelt". –

+0

@ LasseV.Karlsen Um fair zu sein, ist der Fehler in Code-Kommentare eingebettet, obwohl ich zustimme, dass es offensichtlicher sein sollte. – DavidG

+0

@ LasseV.Karlsen Ich bekomme das, aber ich habe nur dieses Verhalten in der Moq Returns-Funktion bemerkt, und ich bin gespannt, was den Compiler in der Suche nach der richtigen Methode zum Aufrufen auslöst. Ich erwarte, dass es einen Konflikt mit einigen anderen Methoden in Returns gibt, aber welche? –

Antwort

1

als Antwort beantworten, damit ich einige Code einfügen ...

Es ist nicht die Anzahl der Überlastungen wie Lasse V. Karlsen vermuten lässt. Das Verhalten ist auf Casting zurückzuführen. Siehe Kommentare im Code unten:

//works because "eat" knows it's own input type 
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(eat); 

// works because you are explicitly typing input param 
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food)); 

jedoch die Dinge ein bisschen schwieriger, wenn Sie einen Lambda-Ausdruck verwenden, da der Lambda-Ausdruck eigentlich nicht einen Eingabetyp hat

animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food)); 
// is equivalent to: 
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => {return eat(food); }); 

Aber {return eat(food);} doesn‘ Ich weiß, welcher Typ food ist.

Wenn Sie also

animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => eat(food)); 
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => $"Nom nom nom {food}"); 

der Compiler rufen nicht weiß, welche Art Nahrung.

Verwandte Themen