C#语法,将委托分配给一个类,然后再调用

时间:2014-08-05 15:54:20

标签: c# delegates

我对这种C#语法有些困惑。 我试图将一个任意的委托分配给一个班级。

我有一个代理人定义为

delegate string stringCB(string s);
delegate int intCB(int i);

我有一个班级

class run_by_name {
    public string name {get;set;}
    public Delegate method {get;set;}
};

我试图将其实例化

 run_by_name myfuc = new run_by_name(){
     name = "my name",
     method = new stringCB(string s) {
         return " testing " + s;
     };
 };

我真的不清楚在返回类型时如何分配给代理人。此外,我还不确定如何在语法上调用该方法

为什么我要这样做?我只是编写了一些代码,这些代码遵循我在JS中用于事件处理的模式,我只是在制作一个"对象"我可以为一个通用事件处理程序分配任意函数,该处理程序已创建而不是已定义。(重要)

此外,欢迎使用代表的替代方案。 :)

编辑:我以后如何使用
我还没有写过,但我很确定我会这样做。

List<run_by_name> callbacks = new List<run_by_name>();
/* lets say this is initialized and filled at this point */

public object FindAndRunCallback(string Name, object input) {
    foreach(var cb in callbacks) {
        if( cb.name == Name )
            return cb.method(input);
    }
    return null;
}

2 个答案:

答案 0 :(得分:3)

以下是使当前代码正常工作所需的语法:

 method = new stringCB((string s) =>  {
     return " testing " + s;
 })

或者,使用lambda表达式:

 method = new stringCB(s =>" testing " + s)

您可以稍后调用此方法:

string result = (string) myfuc.method.DynamicInvoke("hello");

在不了解您的用例的情况下,很难推荐其他方法,但我建议至少要考虑以下内容:

  • 事件:您的描述听起来非常接近C#中事件和事件处理程序的常见模式。您的事件定义了用于处理它的委托类型,其他地方的代码可以使用与该委托类型匹配的方法订阅该事件。按照惯例,人们通常会将发件人object作为第一个参数传递,并使用一些强类型EventArgs,这样订阅者就不必猜测事件触发时哪些数据可用。
  • Func<>Action<>变体:随着C#演变成更具功能性的语言,程序员不再使用自定义委托类型,而是使用{{1}提供的变体}和Func<>。由于参数仍然是强类型的,因此您可以获得编译语言的大部分优点,但对于传递的实际函数使用一些“鸭子打字”。

    例如,您可以根据您希望代表处理的类型为您的类提供泛型类型:

    Action<>

    然后使用它:

    class run_by_name<T> {
        public string name {get;set;}
        public Func<T, T> method {get;set;}
    };
    
  • var myfuc = new run_by_name<string>{ name = "my name", method = s =>" testing " + s }; string result = myfuc.method("hello"); :此关键字允许您对任何对象进行后期绑定操作。您失去了编译语言的优势,但它极大地提高了与更动态语言的互操作性。例如,可以通过JSON创建对象,并且可以访问该对象,而无需为该对象声明特殊类型,就像在Javascript中一样。

    例如,如果您将dynamic声明更改为:

    method

    然后你可以简单地说:

    public dynamic method {get;set;}
    

答案 1 :(得分:2)

你有选择。 strinCB构造函数需要一个方法,它接受一个字符串参数并返回一个字符串。如果您有一个现有的方法,您可以将它的名称传递给构造函数,或者您可以通过委托语法创建一个匿名方法,如下所示:

method = new stringCB(delegate(string s)
            {
                return " testing " + s;
            })

或使用lambda表达式:

method = new stringCB(s =>
            {
                return " testing " + s;
            })

然后你可以这样称呼它:myfuc.method.DynamicInvoke(YourParameter);

通常,调用委托方法非常简单:

Func<int, int, int> sum = (x, y) => x + y;

Console.WriteLine(sum(2,3)); // with the name of delegate

Console.WriteLine(sum.Invoke(2,3)); // or using Invoke method

但在这种情况下,您需要使用DynamicInvoke,因为您的媒体资源类型为Delegate

除此之外,.NET Framework还有一些有用的内置委托类型,例如FuncActionPredicate等。您可以使用它们而不是创建自己的代理类型代表,只要他们满足您的需求。例如,在这种情况下,您可以使用Func<string,string>代替stringCB

相关问题