Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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#,我真的不太明白这个调用。我知道它所做的是告诉当前操作在它需要运行的线程(UI线程)上运行。但我不明白为什么你可以做这么多不同的版本。例如: this.BeginInvoke(new MethodInvoker(delegate { currping.Text = Status; })); this.BeginInvoke(new Action(() => { currping.Text = Status; })); Action foo = () => { }; 我不明白是否

我真的不太明白这个调用。我知道它所做的是告诉当前操作在它需要运行的线程(UI线程)上运行。但我不明白为什么你可以做这么多不同的版本。例如:

this.BeginInvoke(new MethodInvoker(delegate { currping.Text = Status; }));

this.BeginInvoke(new Action(() => {  currping.Text = Status; }));
Action foo = () => { };
我不明白是否有区别。从我所能掌握的情况来看,他们都会做同样的事情


我在这里遗漏了什么吗?

Action
作为一个普通委托添加到.NET 3.5框架中,它不接受任何参数,也不返回任何内容,而
MethodInvoker
从1.1开始就存在,因此您通常只会看到使用
MethodInvoker
的旧代码。这两种委托类型具有相同的签名

BeginInvoke()
实际上接受一个
Delegate
对象,因此任何不带参数的委托都可以与该重载一起使用。(对于需要参数的委托,有一个
(委托,对象[])
重载,不过我倾向于使用无参数闭包。)

由于
Delegate
是一种常规类型,因此必须以某种方式指定所提供的委托类型,因为编译器无法以其他方式推断它(请参见下文)。这比
新操作
选项短,但只短了几个字符,实际上并不清楚:

this.BeginInvoke((Action)(() => { ... }));
您必须在此处指定委托类型,因为编译器不知道您需要哪种委托类型。例如:

this.BeginInvoke(new MethodInvoker(delegate { currping.Text = Status; }));

this.BeginInvoke(new Action(() => {  currping.Text = Status; }));
Action foo = () => { };
这是因为编译器可以根据
foo
的类型推断委托类型应该是
Action

// All of these examples cause CS1660.
Delegate foo1 = () => { };
object foo2 = () => { };
var foo3 = () => { };

这些都是编译时错误,因为有许多委托类型与签名“不带参数并返回
void
”匹配,而且编译器不会假装知道您想要的是什么。(在
对象
变量
的情况下,您可能还指的是一个
表达式
对象,它根本不是委托。但是,如果您使用
委托(){}
而不是lambda表达式,则会出现相同的错误。)
操作
作为不带参数且不返回任何内容的常规委托添加到.NET 3.5框架中,而
MethodInvoker
自1.1以来就已存在,因此您通常只能使用
MethodInvoker
查看较旧的代码。这两种委托类型具有相同的签名

BeginInvoke()
实际上接受一个
Delegate
对象,因此任何不带参数的委托都可以与该重载一起使用。(对于需要参数的委托,有一个
(委托,对象[])
重载,不过我倾向于使用无参数闭包。)

由于
Delegate
是一种常规类型,因此必须以某种方式指定所提供的委托类型,因为编译器无法以其他方式推断它(请参见下文)。这比
新操作
选项短,但只短了几个字符,实际上并不清楚:

this.BeginInvoke((Action)(() => { ... }));
您必须在此处指定委托类型,因为编译器不知道您需要哪种委托类型。例如:

this.BeginInvoke(new MethodInvoker(delegate { currping.Text = Status; }));

this.BeginInvoke(new Action(() => {  currping.Text = Status; }));
Action foo = () => { };
这是因为编译器可以根据
foo
的类型推断委托类型应该是
Action

// All of these examples cause CS1660.
Delegate foo1 = () => { };
object foo2 = () => { };
var foo3 = () => { };

这些都是编译时错误,因为有许多委托类型与签名“不带参数并返回
void
”匹配,而且编译器不会假装知道您想要的是什么。(在
对象
变量
的情况下,您可能还意味着一个
表达式
对象,它根本不是委托。然而,如果您使用
委托(){}
而不是lambda表达式,您会得到同样的错误。)

有两个新的东西(
零件和最内圆括号内的零件

MethodInvoker
Action
都是,你需要把它们看作是“函数模式”的定义。这两个“模式”代表的是“一个不接受参数并返回void的函数”

因此,它们都表示完全相同的“模式”,只是为了便于编码,在两个地方定义了它。例如,更明显的是,您计划使用委托调用Winforms表单的方法,使用
MethodInvoker
,而不是使用
操作

// All of these examples cause CS1660.
Delegate foo1 = () => { };
object foo2 = () => { };
var foo3 = () => { };
第二部分是括号内的内容。这两个定义的含义相同,但是模式
()=>{…}
是一个,直到visual studio 2008或更新版本才添加。它们都表示“我在这里内联定义一个函数”,这将创建一个称为的函数,因为它是一个没有名称的函数。您也可以改为传入一个函数名

public void Foo()
{
    this.BeginInvoke(new Action(Bar)); //BeginInvoke will call the function Bar()
}

private void Bar()
{
}

这有两个部分,
newsomething(
part)和最里面括号内的部分

MethodInvoker
Action
都是,你需要把它们看作是“函数模式”的定义。这两个“模式”代表的是“一个不接受参数并返回void的函数”

因此,它们都表示完全相同的“模式”,只是为了便于编码,在两个地方定义了它。例如,更明显的是,您计划使用委托调用Winforms表单的方法,使用
MethodInvoker
,而不是使用
操作

// All of these examples cause CS1660.
Delegate foo1 = () => { };
object foo2 = () => { };
var foo3 = () => { };
第二部分是括号内的内容。这两个定义的含义相同,但是模式
()=>{…}
是一个,直到visual studio 2008或更新版本才添加。它们都表示“我在这里内联定义一个函数”,这将创建一个称为的函数,因为它是一个没有名称的函数。您也可以改为传入一个函数名

public void Foo()
{
    this.BeginInvoke(new Action(Bar)); //BeginInvoke will call the function Bar()
}

private void Bar()
{
}

没什么区别。只是语言正在进化,使代码更容易编写。啊,很高兴知道,MethodInvoker不是