像这样的东西:
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";
})
};
Run Code Online (Sandbox Code Playgroud)
我意识到Select并不打算以这种方式使用.但是,有什么其他方法可以做同样的事情?
Ale*_*kov 20
对于真正的代码使它成为一个函数...对于娱乐目的,C#相当于JavaScript IIFE比Select以下更直接:
var myObject = new MyClass()
{
x =((Func<int>)(() => {return 2;}))(),...
Run Code Online (Sandbox Code Playgroud)
p.s*_*w.g 13
我很惊讶没人提到这个,但你可以使用这个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
};
Run Code Online (Sandbox Code Playgroud)
或者,如果您想避免必须在任何地方指定返回类型(new Lazy<string>因为构造函数不支持类型推断),您可以实现这样的简单泛型方法:
public static T Eval<T>(Func<T> func)
{
return func();
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样打电话:
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";
})
};
Run Code Online (Sandbox Code Playgroud)
更新:C#7引入了本地功能.这些不是真正的 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";
}
Run Code Online (Sandbox Code Playgroud)
这里的关键是GetX可以在相同的方法中声明与myObject共享相同的范围.
这是我的同事的想法:
var myObject = new {
x = new Func<int>(() => {return 2;})()
};
Run Code Online (Sandbox Code Playgroud)
请注意,这是基于阿列克谢的回答。
虽然肯定不是 "官方",但您可以在构造函数中使用可选的命名参数或单独的工厂/构建器方法:
public class MyClass
{
public string x { get; private set; }
public MyClass(Func<string> x = null)
{
if (x != null)
this.x = x();
}
}
Run Code Online (Sandbox Code Playgroud)
用法如下:
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"
Run Code Online (Sandbox Code Playgroud)
所以,这不是你要求的确切语法,但非常接近并且跳过了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;
}
}
Run Code Online (Sandbox Code Playgroud)
具有类似的用法(只需调用工厂方法):
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";
}
);
Run Code Online (Sandbox Code Playgroud)
编辑:嘿,我们在这里.为什么不离开深层并使用单独的构建器和滥用隐式运算符来执行此操作!
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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用方式如下:
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";
}
};
Run Code Online (Sandbox Code Playgroud)
所以现在语法是相同的,除了你必须明确键入你的实例而不是使用var.
获取隐式类型委托可能很棘手,但如果您为其编写自己的静态方法,它就可以工作。
您可以创建一个隐式类型函数,如下所示:
public static class Func {
public static Func<T> Create<T>(
Func<T> func
) =>
func;
}
...
var x = Func.Create(() => "result")();
Assert.AreEqual("result", x);
var x = Func.Create(() => {
// complex logic to create a value
})();
Run Code Online (Sandbox Code Playgroud)
您还可以编写一个来立即计算函数,然后您不需要手动执行此操作:
public static class Func {
public static T Eval<T>(
Func<T> func
) =>
func();
}
...
var x = Func.Eval(() => 5);
Assert.AreEqual(5, x);
Run Code Online (Sandbox Code Playgroud)