是否有任何官方方法可以编写立即调用的函数表达式
本文关键字:调用 表达式 函数 任何 官方 方法 是否 | 更新日期: 2023-09-27 18:27:55
像这样:
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";
})
};
我意识到 Select 不打算以这种方式使用。但是,是的,还有什么其他方法可以做同样的事情?
对于真正的代码,让它成为一个函数...出于娱乐目的,C#等同于JavaScript IIFE比Select
更直接:
var myObject = new MyClass()
{
x =((Func<int>)(() => {return 2;}))(),...
惊讶还没有人提到这一点,但你可以使用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 引入了本地函数。这些不是真正的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
共享相同作用域的相同方法中声明。
这是我的同事想出的:
var myObject = new {
x = new Func<int>(() => {return 2;})()
};
请注意,这是基于阿列克谢的答案。
出于某种原因,很难获得隐式类型的委托,但如果您为它编写自己的静态方法,这并非不可能。
public static class Func {
public static Func<T> Create<T>(
Func<T> func
) =>
func;
}
...
x = Func.Create(() => "result")();
x = Func.Create(() => {
// complex logic to create a value
})();
虽然肯定不是"官方的",但您可以在构造函数中使用可选的命名参数或单独的工厂/生成器方法:
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
.
也许不能完全回答这个问题,但是...我希望在 C# 中使用 IIFE 的一个原因是为在对象上调用的函数赋予更好的含义。在这个例子中,我想给出关于"Click"方法在测试代码中的特定上下文中做什么的含义(我不喜欢注释(。
以前。。。
lastLine.Click(); //click to begin editing line
后。。。
Action<IWebElement> clickToStartEditing = line => line.Click();
clickToStartEditing(lastLine);
后来我发现我可以简单地创建一个具有另一个名称的新方法......
Action clickToStartEditing = lastLine.Click;
clickToStartEditing(lastLine);
最后,简单地以更好的方式命名变量可以更好地解决问题(对我来说(
lastLineForEditing.Click();
这为我解决了一个 IIFE 问题,为方法名称赋予了意义。
你可以做:
global using static System.IIFE;
namespace System {
public static class IIFE {
public static T Scope<T>(Func<T> f) => f();
}
}
然后:
var x = Scope(() => {
var t1 = getVal();
vat t2 = getVal2();
return t1+t2;
});
IIFE的优点是t1和t2不会污染外部范围