我希望我能恰当地提出问题的标题.
在c#中,我可以使用lambdas(作为委托),或者使用较旧的委托语法来执行此操作:
Func<string> fnHello = () => "hello";
Console.WriteLine(fnHello());
Func<string> fnHello2 = delegate()
{
return "hello 2";
};
Console.WriteLine(fnHello2());
Run Code Online (Sandbox Code Playgroud)
那么为什么我不能"内联"lambda或委托体,并避免在命名变量中捕获它(使其匿名)?
// Inline anonymous lambda not allowed
Console.WriteLine(
(() => "hello inline lambda")()
);
// Inline anonymous delegate not allowed
Console.WriteLine(
(delegate() { return "hello inline delegate"; })()
);
Run Code Online (Sandbox Code Playgroud)
在javascript中工作的示例(仅用于比较)是:
alert(
(function(){ return "hello inline anonymous function from javascript"; })()
);
Run Code Online (Sandbox Code Playgroud)
这会产生预期的警报框.
更新:看起来你可以在C#中使用内联匿名lambda,如果你适当地进行转换,但是()的数量开始让它变得难以驾驭.
// Inline anonymous lambda with appropriate cast IS allowed
Console.WriteLine(
((Func<string>)(() => "hello inline anonymous …Run Code Online (Sandbox Code Playgroud) 可能重复:
C#为什么不能将匿名方法分配给var?
我在c#中有以下声明
Func <int, int, int> add = (x, y) => x + y;
Run Code Online (Sandbox Code Playgroud)
但是当我用以下代替左手边的声明时
var add = (x, y) => x + y;
Run Code Online (Sandbox Code Playgroud)
我收到编译错误(无法将lambda表达式赋值给隐式类型的局部变量).为什么?
我正在尝试学习C#对匿名类型的限制.请考虑以下代码:
var myAwesomeObject = new {
fn1 = new Func<int>(() => { return 5; }),
fn2 = () => { return 5; }
};
Run Code Online (Sandbox Code Playgroud)
所以我们有两个实际上是函数的属性:
fn1:A Func<int>返回5.fn2:返回的lambda函数5.C#编译器很乐意使用fn1,但抱怨fn2:
无法将lambda表达式赋给匿名类型属性.
有人可以解释为什么一个是好的但另一个不是吗?
在使用C#进行编程的不同时间,我发现自己处于需要定义lambda(或匿名委托)并在同一行中调用它的情况.在这一点上,我能够做到这一点的"最干净"的方式是这样的:
bool foo_equals_bar = new Func<String, bool>(str => str.Equals("foo"))("bar");
Run Code Online (Sandbox Code Playgroud)
我希望能够写下以下内容:
bool foo_equals_bar = (str => str.Equals("foo"))("bar");
Run Code Online (Sandbox Code Playgroud)
不幸的是,这似乎不起作用.我会很高兴知道:
(str => str.Equals("foo"))这样返回的是什么,可用于初始化a Func<String, bool>,但不能像a一样进行求值Func<String, bool>?我应该指出我在C#3(VS2008)中工作,所以如果解决方案只存在于C#4中,请提及.(我仍然想知道,即使目前我无法获得解决方案).
谢谢
我似乎无法将二进制操作应用于lambda表达式,委托和方法组.
dynamic MyObject = new MyDynamicClass();
MyObject >>= () => 1 + 1;
Run Code Online (Sandbox Code Playgroud)
第二行给我错误: Operator '>>=' cannot be applied to operands of type 'dynamic' and 'lambda expression'
为什么?
操作员功能不是由我的自定义TryBinaryOperation覆盖决定的吗?
我已经搜索了一下类型推断,但我似乎无法将任何解决方案应用于我的特定问题.
我在构建和传递函数方面做了很多工作.在我看来,它应该能够推断出int类型.我唯一能想到的是lambda返回类型不是由类型推断算法检查的.我已经删除了不必要的逻辑以更清楚地显示问题.
Func<T> Test<T>(Func<Func<T>> func)
{
return func();
}
Run Code Online (Sandbox Code Playgroud)
这编译:
Func<int> x = Test<int>(() =>
{
int i = 0;
return () => i;
});
Run Code Online (Sandbox Code Playgroud)
但这会给出错误"无法根据用法推断出方法的类型参数.请尝试明确指定类型参数":
Func<int> x = Test(() =>
{
int i = 0;
return () => i;
});
Run Code Online (Sandbox Code Playgroud)
我想我只想知道为什么它以这种方式工作和任何变通方法.
在c#中我可以用速记做这样的事情吗?
bool validName = true;
if (validName)
{
name = "Daniel";
surname = "Smith";
}
else
{
MessageBox.Show("Invalid name");
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道类似的东西是否会起作用,但在这个确切的场景中,我知道你可以分配值,如果我的名字= validName?"丹尼尔":"无效",但我只是想知道我能否做到以下?
validName ?
{
name = "Daniel";
surname = "Smith";
}
:
{
MessageBox.Show("Invalid name");
}
Run Code Online (Sandbox Code Playgroud) 抓我的头.以下陈述有什么问题?
var EncFunc = (encrypt ? Encryption.Encrypt : Encryption.Decrypt);
Run Code Online (Sandbox Code Playgroud)
encrypt是bool,两个函数Encryption.Encrypt和Encryption.Decrypt具有相同的类型Func<string, string>,但它告诉我:
CS0173无法确定条件表达式的类型,因为"方法组"和"方法组"之间没有隐式转换
我已经经历过这个和这个,但无法理解为什么编译器无法确定这两个函数的类型.
NB我知道这可以通过显式转换来修复.我对理解"为什么"部分更感兴趣.
这在 C# 中可能吗?以下代码产生编译器错误。
HashSet<Task<(string Value, int ToNodeId)>> regionTasks =
new HashSet<Task<(string Value, int ToNodeId)>>();
foreach (Connection connection in Connections[RegionName])
{
regionTasks.Add(async () =>
{
string value = await connection.GetValueAsync(Key);
return (value, connection.ToNode.Id);
}());
}
Run Code Online (Sandbox Code Playgroud)
C# 编译器抱怨“错误 CS0149:应为方法名称。” 无法推断 lambda 方法的返回类型。
请注意我在 lambda 块关闭后立即通过 () 调用 lambda 方法的技术 {}。这确保Task返回 a ,而不是 a Func。
VB.NET 编译器理解这种语法。我惊讶地发现 VB.NET 编译器胜过 C# 编译器的示例。有关完整故事,请参阅我的An Async Lambda Compiler Error Where VB Outsmarts C#博客文章。
Dim regionTasks = New HashSet(Of Task(Of (Value As String, …Run Code Online (Sandbox Code Playgroud) 我想知道是否有可能使变量的"动态"类型适用于匿名委托.
我尝试过以下方法:
dynamic v = delegate() {
};
Run Code Online (Sandbox Code Playgroud)
但后来我收到以下错误消息:
Cannot convert anonymous method to type 'dynamic' because it is not a delegate type
不幸的是,以下代码也不起作用:
Delegate v = delegate() {
};
object v2 = delegate() {
};
Run Code Online (Sandbox Code Playgroud)
如果我想创建一个接受任何类型的委托的方法,即使是内联声明的委托,我该怎么办?
例如:
class X{
public void Y(dynamic d){
}
static void Main(){
Y(delegate(){});
Y(delegate(string x){});
}
}
Run Code Online (Sandbox Code Playgroud) 参考为什么不能将匿名方法分配给var?,我知道C#不支持以下内容:
var func = (x,y) => Math.Log(x) + Math.Log(y);
Run Code Online (Sandbox Code Playgroud)
但是,我可以创建一个方法,Func形式如下:
public static Func<T,T,T> Func<T>(Func<T,T,T> f) => f;
Run Code Online (Sandbox Code Playgroud)
然后做:
var func = Func<double>((x,y) => Math.Log(x) + Math.Log(y));
Run Code Online (Sandbox Code Playgroud)
那将编译得很好.但是,对于参数和返回值具有不同类型的lambda,事情变得奇怪.例如,如果我有一个方法:
public static Func<T1,T2,T3> Func<T1,T2,T3>(Func<T1,T2,T3> f) => f;
Run Code Online (Sandbox Code Playgroud)
我可以这样做:
var func = Func((double x, double y) => $"{x + y}");
Run Code Online (Sandbox Code Playgroud)
那也将编译.所以C#编译器似乎能够推断出lambda的返回类型.但是,以下内容将无法编译:
var func = Func((x,y) => Math.Log(x) + Math.Log(y));
Run Code Online (Sandbox Code Playgroud)
因为编译器似乎无法推断它们在体内使用的方式x和类型y.
所以,我的问题是:关于lambda表达式类型推断的明确规则是什么; 编译器将推断出什么,不会推断出什么?
是否可以在C#中为表达式赋值,以便我不必为它编写方法?例如,名为canBuild的变量等于表达式"numResources> 50".无论何时调用该变量,它都会重新计算它的值.我已经尝试过研究lambda,但我并不真正理解文档.
谢谢
编辑:
这是我尝试使用lamdas的尝试:
public void setStateFloat(float variable, float comparison, int compareType)
{
Func<bool> stateEval;
switch(compareType)
{
case 0:
stateEval = () => variable < comparison;
break;
case 1:
stateEval = () => variable > comparison;
break;
case 2:
stateEval = () => variable == comparison;
break;
}
}
Run Code Online (Sandbox Code Playgroud)
如果变量和比较不是使用此函数的对象本地(如在引用另一个对象变量的对象中),这是否有效.我怀疑它,因为它只是变量的副本,而不是指向原始变量存储位置的指针/引用.
另外,如果我想存储对该函数的引用,我该怎么做?
这背后的原因是我正在为设计人员开发一个高度结构化的模块化系统,其中一个要求是从他们的输入创建一个最初计算然后在运行时使用的函数.欢迎采用其他方法.
好的谢谢.
c# ×12
lambda ×5
dynamic ×2
asynchronous ×1
delegates ×1
func ×1
generics ×1
shorthand-if ×1
task ×1
vb.net ×1