为什么我们使用类名称调用委托?为什么不能在类Object列表中列出?

时间:2015-03-27 06:32:32

标签: c# delegates

见下面的例子......

public class Test
  {
    public delegate void Logger(string s);

    public void Process(Logger logger)
    {
      if (logger!= null)
      {
        logger("Process Started");
      }
      if (logger != null)
      {
        logger("Process End");
      }
    }
  }

  class Program
  {
    public static void LogMe(string s)
    {
      Console.WriteLine(s);
    }

    static void Main(string[] args)
    {
      Test obj = new Test();
      Test.Logger del = new Test.Logger(LogMe);
      obj.Process(del);
    }
  }

这里,委托记录器是在类Test中编写的...当我创建Class Test的对象时,即obj ...委托记录器没有列在那里,当尝试使用类名时,我能够得到记录器。 / p>

我知道委托概念,但我只是想了解为什么委托没有列在obj列表中。

2 个答案:

答案 0 :(得分:2)

  

当我创建Class Test的对象时,即obj ...代理Logger没有列在那里,当尝试使用类名时,我能够获得Logger

嵌套在另一个类型中的类型不是实例成员。即使关键字static未应用于嵌套类型的声明,在某种意义上它仍然是“静态的”。 (虽然,在你可以调用方法或访问字段或属性的意义上,它不是运行时成员,所以我不确定我是否真的认为它是“静态成员”)。

更基本的是,委托类型Logger绝不是该类的每个实例成员。即每个实例都不能有不同的Logger。因此,通过实例引用访问Logger类型没有任何意义。

对于不是每个实例的类的任何成员,您可以使用类型名称来访问它。例如。 Test.Logger

如果委托类型在某种程度上对Test是唯一的,并且与Test的公共API紧密相关,那么嵌套类型也许在这里有意义。也就是说,我倾向于试图避免使用公共嵌套类型,仅在看起来真正时才使用它们,这是正确的做法,主要是因为这个特定的问题。我不喜欢使用包含类型名称的高质量类型名称。 :)

你确实有其他选择:

  • 甚至不声明自定义委托类型。只需使用预定义的一个。在您的示例中,Action<string>也可以正常工作。
  • 不要嵌套类型。然后它只需要使用命名空间限定,当然你可以使用using语句隐式。
  • 别名类型。例如。您可以在要使用该类型的源代码文件的顶部写下using Logger = MyNamespace.Test.Logger;,然后只需使用较短的Logger就可以使用它。 (当然,将MyNamespace替换为类型的实际完全限定名称空间。

答案 1 :(得分:0)

如果您在名称空间级别提及测试类之外的委托:

namespace StackOverflow{
  public delegate void Logger(string s);
  public class Test
  {
  }
}

您可以在没有测试类前缀的情况下访问Logger类型。部分原因是我们经常将Delegate视为嵌套类型,因此我们没有意识到它是一种类型,并且可以在命名空间中独立存在。