2013-08-16 25 views
18

事情是這樣的:有沒有官方的方式來編寫立即調用的函數表達式?

var myObject = new MyClass() 
{ 
    x = " ".Select(y => 
    { 
     //Do stuff.. 
     if (2 + 2 == 5) 
      return "I like cookies"; 
     else if (2 + 2 == 3) 
      return "I like muffins"; 
     //More conditions... 
     else 
      return "I'm a bitter old man"; 
    }) 
}; 

我意識到選擇不打算使用這種方式。但是,有什麼其他方法可以做同樣的事情?

+5

如果它太長,把它放在一個函數? –

+4

'有什麼其他的方法可以做同樣的事情?'你在做什麼?該物業在哪裏? – I4V

+4

我不會在select語句中使用返回值(Plus基礎數學陳述你是一個苦澀的老頭) – Sayse

回答

11

我很驚訝,但沒有一個人提到這一點,但你可以使用Lazy<T>類:

var myObject = new MyClass() 
{ 
    x = new Lazy<string>(() => 
    { 
     //Do stuff.. 
     if (2 + 2 == 5) 
      return "I like cookies"; 
     else if (2 + 2 == 3) 
      return "I like muffins"; 
     //More conditions... 
     else 
      return "I'm a bitter old man"; 
    }).Value // <-- Evaluate the function here 
}; 

另外,如果你想避免指定返回類型的任何地方(你new Lazy<string>因爲做構造器不支持類型推斷),可以實現這樣一個簡單的通用方法:

public static T Eval<T>(Func<T> func) 
{ 
    return func(); 
} 

然後你可以這樣調用:

var myObject = new MyClass() 
{ 
    x = Eval(() => 
    { 
     //Do stuff.. 
     if (2 + 2 == 5) 
      return "I like cookies"; 
     else if (2 + 2 == 3) 
      return "I like muffins"; 
     //More conditions... 
     else 
      return "I'm a bitter old man"; 
    }) 
}; 

更新:C#7引入local functions。這些不是真的 IFFE,但它們可能會解決各種相關問題。例如:

var myObject = new MyClass() 
{ 
    x = GetX() 
}; 

string GetX() { 
    //Do stuff.. 
    if (2 + 2 == 5) 
     return "I like cookies"; 
    else if (2 + 2 == 3) 
     return "I like muffins"; 
    //More conditions... 
    else 
     return "I'm a bitter old man"; 
} 

這裏的關鍵是,GetX可以在同一個方法中被聲明爲myObject共享相同的範圍,因爲它。

+0

這是完美的。它是有道理的,它沒有凌亂的括號,並且在那裏沒有進行投射。 – elite5472

13

對於真正的代碼,使它成爲一個功能...出於娛樂的目的C#相當於JavaScript IIFE更直接比Select

var myObject = new MyClass() 
{ 
    x =((Func<int>)(() => {return 2;}))(),... 
+0

+1爲了得到這個問題的目的:D – elite5472

+0

我只是用它來填充一些測試數據。 – QueueHammer

6

雖然肯定「官方」,你可以使用可選命名在構造參數或單獨的工廠/助洗劑的方法:

public class MyClass 
{ 
    public string x { get; private set; } 

    public MyClass(Func<string> x = null) 
    { 
     if (x != null) 
      this.x = x(); 
    } 
} 

與像用法:

var myClass = new MyClass(
     x:() => 
      { 
       //Do stuff.. 
       if (2 + 2 == 5) 
        return "I like cookies"; 
       else if (2 + 2 == 3) 
        return "I like muffins"; 
       //More conditions... 
       else 
        return "I'm a bitter old man"; 
      } 
    ); 

    Console.WriteLine(myClass.x); //"I'm a bitter old man" 

所以,這不是你問的確切語法,但八九不離十,並跳過了LINQ的怪事。

那就是說,我不是就像吧。只是提供它作爲思考的食物。 :)


編輯:我想我會添加一個工廠方法的風格,因爲它是合理的,你正在使用此上,你不能(或不願)改變其構造函數的類:

public static class MyFactory 
{ 
    public static MyClass CreateMyClass(Func<string> x = null) 
    { 
     var myClass = new MyClass() 

     if (x != null) 
       myClass.x = x(); 

     return myClass; 
    } 
} 

類似用途(只是調用一個工廠方法代替):

var myClass = MyFactory.CreateMyClass(
    x:() => 
     { 
      //Do stuff.. 
      if (2 + 2 == 5) 
       return "I like cookies"; 
      else if (2 + 2 == 3) 
       return "I like muffins"; 
      //More conditions... 
      else 
       return "I'm a bitter old man"; 
     } 
); 

編輯:哎,而我們在這。爲什麼不走出最後一步,並與一個單獨的建設者和濫用隱式運營商!

public class MyClassBuilder 
{ 
    public Func<string> x { get; set; } 

    public static implicit operator MyClass(MyClassBuilder builder) 
    { 
     var myClass = new MyClass(); 

     if (builder.x != null) 
      myClass.x = builder.x(); 

     return myClass; 
    } 
} 

有了這樣的用法:

MyClass myClass = new MyClassBuilder 
{ 
    x =() => 
     { 
      //Do stuff.. 
      if (2 + 2 == 5) 
       return "I like cookies"; 
      else if (2 + 2 == 3) 
       return "I like muffins"; 
      //More conditions... 
      else 
       return "I'm a bitter old man"; 
     } 
}; 

所以,現在的語法相同除了你必須明確地類型,而不是使用var您的實例。

+0

雖然第一個例子很有趣,但它不是提問者想要的。第二個例子是我見過的最乾淨的,並得到了重點。 –

4

這裏是我的同事想出了:

var myObject = new { 
    x = new Func<int>(() => {return 2;})() 
}; 

請注意,這是基於阿列克謝的答案。

+0

@DanielGimenez它編譯。我只是在LinqPad上運行它。它也做它應該做的事情。 – elite5472

+0

它編譯並運行在我的機器上,LinqPad和visual studio上。是的,這是基於Alexi的回答。 – elite5472

+0

好的。我看到了我的錯誤,在原始文章中有字符串,但是您在此處將其更改爲int。 –

相關問題