Something like this:
var myObject = new MyClass()
{
x = \" \".Select(y =>
{
//Do stuff..
if (2 + 2 == 5)
return \"I like c
While certainly not "official", you could use optional named parameters in the constructor or a separate factory/builder method:
public class MyClass
{
public string x { get; private set; }
public MyClass(Func<string> x = null)
{
if (x != null)
this.x = x();
}
}
with usage like:
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"
So, it's not the exact syntax you were asking for, but pretty close and skips the LINQ weirdness.
That said, I don't like it. Just offering it as food for thought. :)
EDIT: I figured I'd add a factory method style since it's plausible you're using this on a class that you can't (or don't want to) change its constructor:
public static class MyFactory
{
public static MyClass CreateMyClass(Func<string> x = null)
{
var myClass = new MyClass()
if (x != null)
myClass.x = x();
return myClass;
}
}
With similar usage (just calling a factory method instead):
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";
}
);
EDIT: And hey, while we're at it. Why not go off the deep end and do it with a separate builder and abuse implicit operators!
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;
}
}
With usage like:
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";
}
};
So now the syntax is identical, except you have to explicitly type your instance instead of using var
.
I'm surprised no one's mentioned this yet, but you could use the Lazy<T> class:
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
};
Alternatively, if you want to avoid having to specify the return type anywhere (as you do with new Lazy<string>
because constructors do not support type inference), you can implement a simple generic method like this:
public static T Eval<T>(Func<T> func)
{
return func();
}
And then you can call like this:
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";
})
};
Update: C#7 introduces local functions. These are not really IFFEs, but they may solve a variety of related issues. For example:
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";
}
The key here is that GetX
can be declared within the same method as myObject
share the same scope as it.
For real code make it a function... For entertainment purposes C# equivalent of JavaScript IIFE is more direct than Select
:
var myObject = new MyClass()
{
x =((Func<int>)(() => {return 2;}))(),...
Maybe not quite answering the question but ... one reason I wanted IIFE in C# was to give better meaning to a function being called on an object. In this example I wanted to give meaning as to what the 'Click' method does in a particular context within test code (and I do not like comments).
Before ...
lastLine.Click(); //click to begin editing line
After ...
Action<IWebElement> clickToStartEditing = line => line.Click();
clickToStartEditing(lastLine);
Later I discovered I could simply create a new method with another name ...
Action clickToStartEditing = lastLine.Click;
clickToStartEditing(lastLine);
Finally simply naming the variable in a better way can better solve the issue (for me)
lastLineForEditing.Click();
This solved an IIFE issue for me, to give meaning to the method name.
For some reason it's really hard to get implicitly typed delegates, but it's not impossible if you write your own static methods for it.
public static class Func {
public static Func<T> Create<T>(
Func<T> pFunc
) =>
pFunc;
}
...
x = Func.Create(() => "result")();
x = Func.Create(() => {
// complex logic to create a value
})();
Here is what my coworker came up with:
var myObject = new {
x = new Func<int>(() => {return 2;})()
};
Note that this is based Alexei's answer.