Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在短时间内将方法作为委托传递?_C# - Fatal编程技术网

C# 如何在短时间内将方法作为委托传递?

C# 如何在短时间内将方法作为委托传递?,c#,C#,我有一个my方法X,它调用我希望作为参数传递的方法Y。 挑战在于Y实际上可以是任何方法,但在我的特定情况下,它可以是动作、Func或Func。这里是接收端: 空XDelegate y{ 如果y是动作动作{/*…*/} 如果y是Func boolFunction{/*…*/} else如果y如果Func intFunction{/*…*/} 否则抛出新的NotImplementedException; //根据“y”做其他事情` } 将其用作: XY; 不编译并显示: 错误CS1503参数1:无法

我有一个my方法X,它调用我希望作为参数传递的方法Y。 挑战在于Y实际上可以是任何方法,但在我的特定情况下,它可以是动作、Func或Func。这里是接收端:

空XDelegate y{ 如果y是动作动作{/*…*/} 如果y是Func boolFunction{/*…*/} else如果y如果Func intFunction{/*…*/} 否则抛出新的NotImplementedException; //根据“y”做其他事情` } 将其用作:

XY; 不编译并显示:

错误CS1503参数1:无法从“方法组”转换为“委托”

但是,像这样调用:

xnewaction=>Y; 工作!我的问题是它看起来很难看,涉及无用的样板代码,使用lambdas只调用方法,而不是将方法作为委托传递

当然,它可以通过创建3个不同的方法签名来解决,接受Action、Func和Func作为委托参数,但同样——样板代码、重复代码——所有我想在这里避免的事情

那么,用C语言简洁而优雅地解决这个问题的方法是什么呢


编辑:澄清问题-这是一个问题的代码类型。我想做的事情有很多很多种方法,它们都很有效,我甚至可以选择快速和慢速解决方案,因为在我的具体案例中,性能并不重要,它处理用户点击,世界上所有的反射调用都比用户的鼠标快得多。我问这个问题是为了提高我的高级C语言技能,因为我猜有一些语法风格更优雅,更适合特定的挑战。这就是我从零开始学习C的方式。如果不知道异步/等待语法,可以使用回调;如果不知道LINQ,可以使用循环。如果不知道如何使用泛型,可以传递装箱对象。如果有一种专门的语言功能可以更好地表达这个想法,我想学习它。

发生错误的原因是您正在传递Y,这可能是指任何名为Y的重载。这可能是返回int、传递字符串等。编译器不知道要使用哪个重载,因此它会给您该错误。您只需要告诉它是什么委托类型:

新行动; 动作; 这需要对代码稍作修改,但是 将X的定义更改为 私有void XTDelegate del其中TDelegate:Delegate { 如果del是动作动作{/*…*/} else如果del是Func boolFunction{/*…*/} else如果del是Func intFunction{/*…*/} 否则抛出新的NotImplementedException; //根据“y”做其他事情` } ReSharper实际上建议将其转换为交换机:

私有void XTDelegate del其中TDelegate:Delegate { 开关del { 案例操作操作:/**/ 打破 case Func boolffunction:/**/ 打破 case Func intFunction:/**/ 打破 违约: 抛出新的NotImplementedException; } //根据“y”做其他事情` }
另外,我认为泛型是最有效的,而Xnew Action=>Y是不必要的冗长,并使编译器引入额外的函数。如果必须使用它,请将其简化为Xnew ActionY

发生错误的原因是您正在传递Y,这可能是指任何名为Y的重载。这可能是返回int、传递字符串等。编译器不知道要使用哪个重载,因此它会给您该错误。您只需要告诉它是什么委托类型:

新行动; 动作; 这需要对代码稍作修改,但是 将X的定义更改为 私有void XTDelegate del其中TDelegate:Delegate { 如果del是动作动作{/*…*/} else如果del是Func boolFunction{/*…*/} else如果del是Func intFunction{/*…*/} 否则抛出新的NotImplementedException; //根据“y”做其他事情` } ReSharper实际上建议将其转换为交换机:

私有void XTDelegate del其中TDelegate:Delegate { 开关del { 案例操作操作:/**/ 打破 case Func boolffunction:/**/ 打破 case Func intFunction:/**/ 打破 违约: 抛出新的NotImplementedException; } //根据“y”做其他事情` }
另外,我认为泛型是最有效的,而Xnew Action=>Y是不必要的冗长,并使编译器引入额外的函数。如果您必须使用它,请将其简化为Xnew ActionY

使用一种重载方法的解决方案:

班级计划 { 静态环[]args { 调用方法类; 调用方法工具; 调用方法; } 公共静态void InvokeMethodAction x { x、 调用; } 公共静态void InvokeMethodFunc x { InvokeMethod=>x; } 公共静态 类MethodVoid { } 公共静态布尔方法布尔 { 返回true; } 公共静态int?MethodInt { 返回42; } }
使用一种重载方法的解决方案:

班级计划 { 静态环[]args { 调用方法类; 调用方法工具; 调用方法; } 公共静态void InvokeMethodAction x { x、 调用; } 公共静态void InvokeMethodFunc x { InvokeMethod=>x; } 公共静态void方法void { } 公共静态布尔方法布尔 { 返回true; } 公共静态int?MethodInt { 返回42; } }

你不需要对返回值做任何事情吗?你能给我们展示一个完整的、有效的代码示例吗,即使它很难看,这样我们就可以使用它了?Xnew Action=>Y;正在创建一个匿名方法,这涉及到资源和时间开销。在特定情况下,您可以使用XActionY,这将隐式地起作用,因为操作是从委托派生的。您想要多短?xActy够短吗?@johnathanbarclayxActy、XFuncY等。。。当通过传递y方法调用XDelegate y时,方法的类型是已知的,并且适当的强制转换可以轻松编写。您不需要对返回值进行任何处理吗?您能否向我们展示一个完整的、有效的代码示例,即使它很难看,这样我们就可以使用它了?Xnew Action=>y;正在创建一个匿名方法,这涉及到资源和时间开销。在特定情况下,您可以使用XActionY,这将隐式地起作用,因为操作是从委托派生的。您想要多短?xActy够短吗?@johnathanbarclayxActy、XFuncY等。。。当通过传递y方法调用XDelegate y时,该方法的类型是已知的,并且正确的强制转换是可写的,不费吹灰之力。哇,这看起来很有希望,我像上面那样更改了签名,但我只得到了另一个编译器错误:无法从用法推断方法X的类型参数。然后,当我以Func的形式提供类型,并且我的方法Y可以作为Func传递时-I get无法从“方法组”转换为“Func”。顺便说一句,在示例的第一行应该有Delegate,而不是Delegate。请注意,Delegate作为一般约束至少需要C7.3@Harry,我已经解决了约束问题。我不确定你的错误是什么,它对我很好:public void Test{XY;}private bool Y{return false;}private void XTDelegate del where TDelegate:Delegate{}@Harry你有什么问题吗?@RowanRadosav McRae此刻:没有。然而,修改后的版本可以工作,我读了更多关于动态调用的巨大成本的内容,并决定对我的委托施加一个约束,使其始终返回一个值。然后,我可以使用泛型类型而不是委托类型,委托类型更快、更容易调试。顺便说一句,接受Func而不是Delegate会使编译器中的类型推断正常工作,因此XY是一个有效的调用。哇,这看起来很有希望,我像上面那样更改了签名,但我刚刚得到另一个编译器错误:无法从用法推断方法X的类型参数。然后,当我以Func的形式提供类型,并且我的方法Y可以作为Func传递时-I get无法从“方法组”转换为“Func”。顺便说一句,在示例的第一行应该有Delegate,而不是Delegate。请注意,Delegate作为一般约束至少需要C7.3@Harry,我已经解决了约束问题。我不确定你的错误是什么,它对我很好:public void Test{XY;}private bool Y{return false;}private void XTDelegate del where TDelegate:Delegate{}@Harry你有什么问题吗?@RowanRadosav McRae此刻:没有。然而,修改后的版本可以工作,我读了更多关于动态调用的巨大成本的内容,并决定对我的委托施加一个约束,使其始终返回一个值。然后,我可以使用泛型类型而不是委托类型,委托类型更快、更容易调试。顺便说一句,接受Func而不是Delegate会使编译器中的类型推断正常工作,因此XY是一个有效的调用。另外,一个重载也是可以接受的,特别是当代码中使用多个T时。另一个优点是类型是在编译时设置的,而不是在运行时设置的。如果我强迫我的参数为Func,甚至不需要重载。同样好的是,一个重载是可以接受的,特别是当代码中使用了许多T时。另一个优点是类型是在编译时设置的,而不是在运行时设置的。如果我强迫我的参数为Func,那么就不需要重载了。