C# 在创建过程中向委托传递参数,并可能像std::占位符一样使用它

C# 在创建过程中向委托传递参数,并可能像std::占位符一样使用它,c#,delegates,C#,Delegates,我目前正在阅读有关委托的资料,我想知道是否有办法创建委托并在创建过程中向该委托传递参数 假设我有这个方法 public void test(int a,int b); 现在我能做到了 public delegate void DelegateWithParameter(int a,int b); DelegateWithParameter d = new DelegateWithParameter(test); d(1,2); //Works 现在,我如何创建一个包含参数的委托,这样我就可

我目前正在阅读有关委托的资料,我想知道是否有办法创建委托并在创建过程中向该委托传递参数

假设我有这个方法

public void test(int a,int b);
现在我能做到了

public delegate void DelegateWithParameter(int a,int b);

DelegateWithParameter d = new DelegateWithParameter(test);
d(1,2); //Works
现在,我如何创建一个包含参数的委托,这样我就可以简单地执行
d()


我还可以传入部分参数吗?就像在创建代理时传入第二个参数,然后在使用过程中传入第一个参数一样?我知道C++中使用STD:占位符。我想知道C#是否有类似的东西

好吧,如果您的委托参数列表是静态的,并且您总是提供相同的值,那么为什么您有一个呢?所以只要用这个:

public delegate void DelegateWithParameter();

DelegateWithParameter d = new DelegateWithParameter(() => test(2, 1));
d(); //Works

那么,如果您的委托参数列表是静态的,并且您总是提供相同的值,那么为什么您甚至有一个?所以只要用这个:

public delegate void DelegateWithParameter();

DelegateWithParameter d = new DelegateWithParameter(() => test(2, 1));
d(); //Works

委托基本上是一个函数签名

public delegate void DelegateWithParameters(int a, int b);
您的委托有一个函数的签名,该函数接受2个整数作为参数并返回void。为了调用该类型的委托,必须使用两个int参数

但是,您可以将该委托包装在另一个方法中,这样就不必提供参数。假设我想用一组默认参数调用上面的委托。 现在,我可以从任何地方调用该函数,而无需为委托指定参数。(尽管它们总是必要的)

或者,您可以拥有一个包含委托的字段的类,例如:

class DelegateInvoker
{
    private DelegateWithParameters method;
    public DelegateInvoker(DelegateWithParameters method)
    {
        this.method = method ?? throw new ArgumentNullException(nameof(method));
    }

    // Note this signature is parameterless
    public void InvokeDelegate()
    {
        // but you do call the delegate with the required parameters
        this.method(1, 2);
    }
}

// Then call it like this
var delegateInvoker = new DelegateInvoker(Test);
delegateInvoker.InvokeDelegate();
更内联的方法是动态创建函数,但基本上是一样的。您可以定义一个新函数来包装委托

DelegateWithParameters method = Test;

// define a new, parameterless method to wrap the delegate
var delegateInvoker = () => method(1, 2);
delegateInvoker();
最后,请注意,新创建的函数实际上有另一个签名。因此,您可以将我们的新函数定义为如下委托:

delegate void ParameterlessDelegate();
最后一个例子可能是:

DelegateWithParameters method = Test;

// define a new, parameterless method to wrap the delegate
ParameterlessDelegate delegateInvoker = () => method(1, 2);
delegateInvoker(); 

委托基本上是一个函数签名

public delegate void DelegateWithParameters(int a, int b);
您的委托有一个函数的签名,该函数接受2个整数作为参数并返回void。为了调用该类型的委托,必须使用两个int参数

但是,您可以将该委托包装在另一个方法中,这样就不必提供参数。假设我想用一组默认参数调用上面的委托。 现在,我可以从任何地方调用该函数,而无需为委托指定参数。(尽管它们总是必要的)

或者,您可以拥有一个包含委托的字段的类,例如:

class DelegateInvoker
{
    private DelegateWithParameters method;
    public DelegateInvoker(DelegateWithParameters method)
    {
        this.method = method ?? throw new ArgumentNullException(nameof(method));
    }

    // Note this signature is parameterless
    public void InvokeDelegate()
    {
        // but you do call the delegate with the required parameters
        this.method(1, 2);
    }
}

// Then call it like this
var delegateInvoker = new DelegateInvoker(Test);
delegateInvoker.InvokeDelegate();
更内联的方法是动态创建函数,但基本上是一样的。您可以定义一个新函数来包装委托

DelegateWithParameters method = Test;

// define a new, parameterless method to wrap the delegate
var delegateInvoker = () => method(1, 2);
delegateInvoker();
最后,请注意,新创建的函数实际上有另一个签名。因此,您可以将我们的新函数定义为如下委托:

delegate void ParameterlessDelegate();
最后一个例子可能是:

DelegateWithParameters method = Test;

// define a new, parameterless method to wrap the delegate
ParameterlessDelegate delegateInvoker = () => method(1, 2);
delegateInvoker(); 

如果没有目标方法,则无法构造委托,即,
new DelegateWithParameter()
将无法编译,其中必须有一个方法。但是,假设您的意思是
newdelegatewithparameter(test)
,那么您可以这样做:
Action d=()=>test(1,2)
,然后调用
d()
调用
测试(1,2)
。很抱歉,让我修复我的代码。要将参数列表缩短1,您只需要另一个只接受一个参数的委托。要么声明一个,要么使用
Action
,这样您就可以执行
Action d=x=>测试(x,2)d(42)
调用
test(42,2)。我很确定这里有一个很好的候选者,只要找到它就行了。你可以看到一个例子。没有目标方法,你无法构造委托,即
new DelegateWithParameter()
不会编译,其中必须有一个方法。但是,假设您的意思是
newdelegatewithparameter(test)
,那么您可以这样做:
Action d=()=>test(1,2)
,然后调用
d()
调用
测试(1,2)
。很抱歉,让我修复我的代码。要将参数列表缩短1,您只需要另一个只接受一个参数的委托。要么声明一个,要么使用
Action
,这样您就可以执行
Action d=x=>测试(x,2)d(42)
调用
test(42,2)。我很确定这里有一个很好的候选者,只要找到它就行了。你可以看到一个例子。不幸的是,它不是静态的。我也想知道这是否可能?如果是这样的话怎么办?@MistyD如果不是静态的,运行时怎么知道你所说的
d()
?在上面的代码中,您当然可以用任何其他调用来替换
test(2,1)
,例如
test(myInt,anotherInt)
。但是要注意这里的闭包,这个方法是静态的。但是我想知道一个委托是否可能在它的某些东西中嵌入部分参数,比如@MistyD,我没有提到关键字
static
。上述方法既适用于静态方法,也适用于非静态方法。我也想知道这是否可能?如果是这样的话怎么办?@MistyD如果不是静态的,运行时怎么知道你所说的
d()
?在上面的代码中,您当然可以用任何其他调用来替换
test(2,1)
,例如
test(myInt,anotherInt)
。但是要注意这里的闭包,这个方法是静态的。但是我想知道一个委托是否可能在它的某些东西中嵌入部分参数,比如@MistyD,我没有提到关键字
static
。上述方法适用于静态方法和非静态方法。