【问题标题】:Why does the delegate take a parameter when no parameter list is specified?为什么没有指定参数列表时,委托要带参数?
【发布时间】:2014-03-26 22:16:06
【问题描述】:

以下代码行我无法完全弄清楚它为什么起作用。

  -->  var blogDelegate = new **Document.SendDoc(blogPoster.PostToBlog);**

SendDoc 没有参数 列表但仍然有效,我不确定为什么会这样。 SendDoc 是返回和 int 且不带参数的委托,但在上面的示例中,SendDoc 有一个 blogPoster.PostToBlog 参数,为什么必须使用 new 关键字来创建委托的实例。这一点我也不确定。我可以看到 Document 的创建和实例,但没有看到创建委托方法实例的原因。

**问题:当委托int SendDoc()声明没有参数列表时,为什么Document.SendDoc(blogPoster.PostToBlog)在参数列表中有参数。


代码:

  class Program
  {
    static void Main(string[] args)
    {
        Document doc = new Document();
        doc.Text = "Document text goes here...";

        var blogPoster   = new BlogPoster();
        var blogDelegate = new Document.SendDoc(blogPoster.PostToBlog);

        doc.ReportSendingResult(blogDelegate);

        var emailSender = new EmailSender();
        var emailDelegate = new Document.SendDoc(emailSender.SendEmail);
        doc.ReportSendingResult(emailDelegate);

        Console.ReadKey();
    }
    }

   class Document
    {
        public string Text { get; set; }
        public delegate int SendDoc();

        public void ReportSendingResult(SendDoc sendingDelegate)
        {
            if (sendingDelegate() == 0)
            {
                Console.WriteLine("Success");
            }
            else
            {
                Console.WriteLine("Unable to send!");
            }
        }
    }

  public class EmailSender
  {
    private int sendResult;
    public int SendEmail()
    {
        Console.WriteLine("Simulating sending email...");
        return sendResult;
    }
  }

  public class BlogPoster
    {
        public int PostToBlog()
        {
            Console.WriteLine("Posting to blog...");
            return 0;
        }
    }
  }

【问题讨论】:

  • Document 在哪个程序集中运行?这是 MS Office 的一部分吗?
  • 您误解了代表的工作方式。当您创建委托对象时,您必须提供委托的目标。该参数不是可选的,它是方法的 name。当您调用委托时,您必须提供目标方法参数。在你的情况下没有。

标签: c#


【解决方案1】:

来自 C# 语言规范,version 5.0,第 7.6.10 节:

新的运算符

new 运算符用于创建类型的新实例。

新表达式有三种形式:

  • 对象创建表达式用于创建类类型和值类型的新实例。

  • 数组创建表达式用于创建数组类型的新实例。

  • 委托创建表达式用于创建委托类型的新实例。

您可能已经习惯在这些表达式的第一个和/或第二个上下文中看到new。但在你当前的代码中,这实际上是第三种形式:

delegate-creation-expression 用于创建 delegate-type 的新实例。

委托创建表达式的参数必须是方法组、匿名函数或编译时类型动态或委托类型的值。如果参数是方法组,则它标识方法,对于实例方法,它标识为其创建委托的对象。如果参数是匿名函数,则直接定义委托目标的参数和方法体。如果参数是一个值,则它标识要为其创建副本的委托实例。

也就是说,参数是标识要将委托实例绑定到哪个方法


根据您的问题:

为什么必须使用 new 关键字来创建委托的实例

它没有。 C# 编译器通常可以在幕后为您创建委托,而无需您显式创建它们。你应该可以写:

Document doc = new Document();
doc.Text = "Document text goes here...";

var blogPoster   = new BlogPoster();
doc.ReportSendingResult(blogPoster.PostToBlog);

var emailSender = new EmailSender();
doc.ReportSendingResult(emailSender.SendEmail);

上述语言规范的第 6.6 节对此进行了介绍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 2010-12-25
    • 1970-01-01
    • 2012-07-16
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多