我具有在C ++中使用的信号及时隙的C ++开发这对我似乎类似于在C#代表。我发现自己处于亏损中搜索由“绑定”提供的功能,觉得我一定是失去了一些东西。

我感觉类似的东西等的下面,这是可能的在C ++中应在C#与代表是可能的。这里是什么,我将会用C ++做一些psudo代码:

Slot<void> someCallback;

int foo(int i)
{
    std::cout << "Value: " << i << "\n";
    return i;
}

int main()
{
    int i = 0;
    Slot<int> someCallback = bind( fun_ptr(foo), i );
    ++i; // added to show that late evaluation would be a non-trivial difference
    int result = someCallback();
    assert( result == 0 );
    return 0;
}

不幸的是,我一直没能找到结合/关于C#代表重新绑定任何引用。我缺少的东西吗?有一些完全不同的方式在C#这样做吗?

有帮助吗?

解决方案

在C#中,我们做这样的事:

class Program {
    static Action Curry<T>(Action<T> action, T parameter) {
        return () => action(parameter);
    }

    static void Foo(int i) {
        Console.WriteLine("Value: {0}", i);
    }
    static void Main(string[] args) {
        Action curried = Curry(Foo, 5);
        curried();
    }
}

显然该方法Foo对应于你的方法Foo,只是用适当的调用Console.WriteLine代替std::cout

接下来,我们声明,接受一个Curry并返回一个Action<T>的方法Action。通常,Action<T>是接受型T并返回void的单个参数的委托。特别地,FooAction<int>因为它接受型int并返回void的一个参数。至于Curry的返回类型,它被声明为Action。一个Action为代表的不具有任何参数和返回void

Curry的定义是相当有趣。我们定义使用lambda表达式是匿名委托的一个非常特殊形式的行动。有效地

() => action(parameter)

说,void参数映射到actionparameter评价。

最后,在Main我们宣布命名Action curried的实例,它是与参数Curry施加Foo5的结果。这起着相同的作用,因为bind(fun_ptr(foo), 5)在C ++例子。

最后,我们通过调用的语法curried新形成的委托curried()。这就好比在你的例子someCallback()

这种情况的花式术语是钻营

作为一个更有趣的例子,考虑以下:

class Program {
    static Func<TArg, TResult> Curry<TArg, TResult>(
        Func<TArg, TArg, TResult> func,
        TArg arg1
    ) {
        return arg => func(arg1, arg);
    }

    static int Add(int x, int y) {
        return x + y;
    }

    static void Main(string[] args) {
        Func<int, int> addFive = Curry<int, int>(Add, 5);
        Console.WriteLine(addFive(7));
    }
}

下面我们宣布接受委托(Curry接受相同类型Func<TArg, TArg, TResult>的两个参数,并返回一些其他类型的TArg的值和类型TResult的参数,并返回一个接受的单个参数的委托的方法TArgTArg并返回型TResultFunc<TArg, TResult>)的值。

然后,作为测试我们声明,接受类型Add的两个参数,并返回型int(一个int)的参数的方法Func<int, int, int>。然后在Main我们实例化一个新的委托命名addFive行为像,增加了五到它的输入参数的方法。因此

Console.WriteLine(addFive(7));

打印12在控制台上。

其他提示

尝试以下方法

class Example {
  static void foo(int i) {
    Console.WriteLine(i);
  }
  public static void Main() {
    Action someCallback = () => foo(5);
    someCallback();
  }
}

或者对于一些更接近C ++计数器部分

class Example {
  static void foo(int i) {
    Console.WriteLine(i);
  }
  static Action bind<T>(Action<T> action, T value) {
    return () => action(value);
  }
  public static void Main() {
    Action someCallback = bind(foo, 5);
    someCallback();
  }
}

解释。这里发生的事情是,我通过一个lambda表达式来创建一个新的委托。拉姆达是开始() =>表达。在这种情况下,它创建一个委托接受没有参数和产生任何值。它与类型Action兼容。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top