使用委托的正确方法是什么?

4

在我的一个实验课程中,我遇到了一个与委托相关的问题,我解决如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DelegateApp
{
    delegate void GreeterDelegate();

    class Program
    {
        static void GreetGoodMorning()
        {
            if (DateTime.Now.ToString().EndsWith("AM"))
                Console.WriteLine("Good Morning!");
        }

        static void GreetGoodEvening()
        {
            if (DateTime.Now.ToString().EndsWith("PM"))
                Console.WriteLine("Good Evening!");
        }

        static void Main(string[] args)
        {
            GreeterDelegate Greeters = new GreeterDelegate(GreetGoodMorning);
            Greeters += GreetGoodEvening;

            Greeters();

            Console.ReadLine();
        }
    }
}

我的做法是在方法中使用条件来检查时间。但实验室的一位教师建议我这样做:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DelegateApp
{
    delegate void GreeterDelegate();

    class Program
    {
        static void GreetGoodMorning()
        {
            Console.WriteLine("Good Morning!");
        }

        static void GreetGoodEvening()
        {
            Console.WriteLine("Good Evening!");
        }

        static void Main(string[] args)
        {
            GreeterDelegate Greeters;

            if (DateTime.Now.ToString().EndsWith("AM"))
                Greeters = new GreeterDelegate(GreetGoodMorning);
            else
                Greeters = new GreeterDelegate(GreetGoodEvening);

            Greeters();

            Console.ReadLine();
        }
    }
}

他建议将条件从方法中移出到Main()方法中。最终结果相同,但我仍然对哪种方式更好感到困惑,特别是考虑到在大型程序中使用委托时,是否应将条件检查移入方法中或保留在外部。

1
代码非常人工,你永远不会使用委托来完成程序的目标。但是委托的重点是使调用稍后进行。因此,在委托目标中检查时间是明智的。在这里绝对需要多个目标,TA试图帮助您避免犯这个错误。 - Hans Passant
3个回答

3
最后一个示例更好,因为你没有冗余的检查方法使用+较少的调用。这将导致更好的性能,因为你的检查将在运行时发生。

2

这不是委托的问题,而是编码实践问题。

在你的代码中,你调用了两个委托,但只有一个在控制台显示文本。

在建议的代码中,仅调用了一个委托。

第二种实现方式更加高效,是你应该使用的方法。从编程角度来看,代码的意图也更为清晰。

每当你要执行某个操作时,最好先决定要执行哪个操作,然后再执行,而不是在每个操作中放置检查。

如果你想吃豆子作为晚餐,你不会把橱柜里的每一罐都拿出来,然后决定是否要吃豆子以及那一罐是否有豆子。相反,你会检查每一罐是否有豆子,然后只拿下一罐有豆子的。


1

这两个代码都不是好的代码。它们只是构造出来的样例,用于展示委托的语法和用法。在这个样例中,你根本不需要使用委托,因为它只是一个普通的函数调用。

以下情况下,委托非常有用:

  • 在运行时动态确定方法(调用方法A、B或C)
  • 回调方法(允许指定由其他方法调用的方法)
  • 多播操作(方法A、B和C由某些代码X调用。X没有任何关于A、B或C的信息)

这两个样例的意思并不相同。我更喜欢第一个版本,因为它做了它所说的事情。GreetGoodMorning检查是否是早上,如果不是则什么也不做。我会将第二个版本重写为以下内容:

 static void Greet() 
 { 
    if (DateTime.Now.ToString().EndsWith("PM")) 
        Console.WriteLine("Good Evening!"); 
    else
        Console.WriteLine("Good Morning!"); 
 } 

没有人应该仅仅为了使用委托而编写代码。

是的,你说得对。我和教师就在这种情况下是否需要委托进行了讨论。完全可以不使用委托来完成。唯一的问题是在哪里放置这些条件检查。 - nayaab
我加入了我的想法。我甚至认为第二个示例并没有更好。 - slfan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接