代表和回调

时间:2009-11-17 03:05:25

标签: c# callback

委托上下文中的术语回调是否意味着,“委托委托给另一个委托工作以完成某项任务”?

示例:( 根据我的理解,我已实施回调,如果错误则纠正我

namespace Test
{
    public delegate string CallbackDemo(string str);  

    class Program
    {
        static void Main(string[] args)
        {
            CallbackDemo handler = new CallbackDemo(StrAnother);
            string substr = Strfunc(handler);
            Console.WriteLine(substr);
            Console.ReadKey(true);
        }

        static string Strfunc(CallbackDemo callback)
        {
           return callback("Hello World");   
        }

        static string StrAnother(string str)
        {
            return str.Substring(1, 3).ToString();
        }
    }
}

请在必要时提供示例。

4 个答案:

答案 0 :(得分:11)

你的例子是一个好的开始,但它是不正确的。您不在方法中创建新委托,它在类的事件声明中使用。请参阅代码的此修改示例:

namespace Test
{
    //In this case, this delegate declaration is like specifying a specific kind of function that must be used with events.
    public delegate string CallbackDemo(string str);
    class Program
    {
        public static event CallbackDemo OnFoobared;
        static void Main(string[] args)
        {
            //this means that StrAnother is "subscribing" to the event, in other words it gets called when the event is fired
            OnFoobared += StrAnother;
            string substr = Strfunc();
            Console.WriteLine(substr);
            Console.ReadKey(true);
            //this is the other use of delegates, in this case they are being used as an "anonymous function". 
            //This one takes no parameters and returns void, and it's equivalent to the function declaration 
            //'void myMethod() { Console.WriteLine("another use of a delegate"); }'
            Action myCode = delegate
            {
                Console.WriteLine("another use of a delegate");
            };
            myCode();
            Console.ReadKey(true);
            //the previous 4 lines are equivalent to the following however this is generally what you should use if you can
            //its called a lambda expression but it's basically a way to toss arbitrary code around
            //read more at http://www.developer.com/net/csharp/article.php/3598381/The-New-Lambda-Expressions-Feature-in-C-30.htm or 
            //http://stackoverflow.com/questions/167343/c-lambda-expression-why-should-i-use-this
            Action myCode2 = () => Console.WriteLine("a lambda expression");
            myCode2();
            Console.ReadKey(true);
        }

        static string Strfunc()
        {
            return OnFoobared("a use of a delegate (with an event)");
        }
        static string StrAnother(string str)
        {
            return str.Substring(1, 3).ToString();
        }
    }
}

我只是在这里划过表面; “for delegate c#”和“lambda expression c#”的搜索堆栈溢出更多!

答案 1 :(得分:5)

回调是委托在调用时执行的内容。例如,当使用委托使用异步模式时,您可以执行以下操作:

public static void Main(string[] args)
{
    Socket s = new Socket(...);

    byte[] buffer = new byte[10];
    s.BeginReceive(buffer, 0, 10, SocketFlags.None, new AsyncCallback(OnMessageReceived), buffer);

    Console.ReadKey();
}

public static void OnMessageReceived(IAsyncResult result)
{
    // ...
}

OnMessageReceived是回调,即通过调用委托执行的代码。有关更多信息,请参阅this Wikipedia article,或参阅Google更多示例。

答案 2 :(得分:3)

回调基本上是传递给过程的委托,该过程将在某个适当的点“回调”。例如,在诸如WebRequest.BeginGetResponse或WCF BeginXxx操作的异步调用中,您将传递AsyncCallback。工作人员将“回调”您传入的任何方法作为AsyncCallback,在这种情况下,当它完成时让您知道它已完成并获得结果。

可以将事件处理程序视为另一个示例。例如,当您将处理程序附加到Click事件时,该按钮将在单击发生时“回调”到该处理程序。

答案 3 :(得分:1)

这将因为正确的原因而被投票。 C#没有实现委托,它实现的是呼叫转发。在这方面,这种错误的术语使用可能是C#的最大问题。

以下ACM论文是对后来被称为代表的内容的第一次描述。基本上,委托似乎是一个对象的实例(它实际上是如何实现的是无关紧要的)。这意味着您可以从代理中调用方法,访问属性等。

http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html

C#实现的是回调或呼叫转发(所有这些都取决于你如何使用它们)。这些不是代表。为了成为委托者,可以像访问对象一样访问对象。

  

当笔将绘图消息委托给原型笔时,它会说“我不知道如何处理绘制消息。如果可以的话,我希望你能为我回答,但如果你有任何进一步的问题,比如我的x变量的价值是什么,或者需要做什么,你应该回过头来问我。“如果有消息如果被委托进一步,所有关于变量值或回复消息的请求的问题都被推断到首先委派消息的对象。 - 亨利利伯曼

那么,它是如何弄乱的?说实话,我不知道。我知道我在C#之前很久就已经使用了代表(已经超过16年了),而且C#实现的代理不是代理。

这里有一个非常好的解释。

http://www.saturnflyer.com/blog/jim/2012/07/06/the-gang-of-four-is-wrong-and-you-dont-understand-delegation/

真正的授权不仅仅是创建回调或呼叫转发。一个真正的委托让我可以调用该对象上的任何方法,获取和/或设置公共属性等 - 就像它是对象本身一样。这比C#“委托”更强大,实际上更容易使用。

OP问道:

  

委托上下文中的术语回调是否意味着,“委托代理人委托给另一个代表以完成某项任务”?

答案是肯定的。代表上下文中的回调可以只能用于完成某项任务。例如,您有一个从天气网站获取数据的类。由于它是非确定性的,因此在接收(并且可能已解析)数据时实现回调将是非常糟糕的。

至于代表团被腐败的原因,我不知道。我期待C#实现真正的授权。