C # лямбда-загадочное поведение - PullRequest
1 голос
/ 29 октября 2009
Func<Classification, string> test1 = c => c.Id = "x"; 
Func<Classification, string> test2 = c => { return c.Id = "x";}; 

Я работал с лямбдами почти год или около того, и довольно разумно с ними, но сегодня я смотрел на NBuilder и увидел странный Func, который, кажется, не соответствует примерам. Я все равно поиграл, и это подтвердилось, но я не понимаю, почему вышеупомянутые компиляции, не говоря уже о запуске. Мы выполняем задание, и, таким образом, выражение ничего не оценивает, верно ??? или нет

Поэтому я подумал, что, может быть, что-то упустил, связанное с лямбдой, поэтому я попробовал что-то еще:

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

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

Конечно, AmIGoingMad терпит неудачу, и "Matt" фактически возвращается.

Почему у нас такое поведение? Где это задокументировано? Это чисто синтаксический ярлык?

Мне кажется, что я упустил что-то фундаментальное в моем понимании лямбды или даже C #.

Чувство тупости.

Ответы [ 5 ]

9 голосов
/ 29 октября 2009

Оператор присваивания имеет возвращаемое значение - это значение является тем, которое было присвоено.Даже C имел это, так что вы могли связать воедино назначения, подобные следующему:

a = b = c = d = 10;

У присваивания d есть возвращаемое значение 10, которое присваивается c, и так далее.

1 голос
/ 29 октября 2009

Как уже говорили другие, присваивание возвращает само значение.

Вы также можете воспользоваться этим следующим образом:

private List<string> theList;
public List<string> LazyList
{
  get { return theList ?? (theList = new List<string>()); }
}
1 голос
/ 29 октября 2009

Это работает, потому что присвоение c.Id = "x" оценивается в значение "x". Вы можете использовать это, например, если вы хотите назначить и проверить значение в одном утверждении (что некоторые люди считают плохой практикой), например:

string s;
if((s = SomeFunction()) != null) { \\do something with s }
1 голос
/ 29 октября 2009

То, что вы видите, - это цепочка присваиваний, которая восходит к C / C ++ Это поддерживает этот сценарий:

int a = b = c = 0;

Или где-то я на самом деле использую это:

public static IEnumerable<string> ReadLines(string filePath)
{
    using (var rdr = new StreamReader(filePath))
    {
       string line;
       while ( (line = rdr.ReadLine()) != null)  // <-----
       {
          yield return line;
       }
    }
}
0 голосов
/ 29 октября 2009

Я не понимаю вашего вопроса.

Вы публикуете код, который выглядит так, как будто вы неправильно поняли разницу между = и ==, а затем явно комментируете, что хотите использовать =, который является оператором присваивания.

Позвольте мне задать вам вопрос:

Почему вы хотите или ожидаете, что это не скомпилируется?

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

По сути, вы делаете это:

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