Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我们使用类名调用委托??为什么可以';它不在类对象列表中列出吗?_C#_Delegates - Fatal编程技术网

C# 为什么我们使用类名调用委托??为什么可以';它不在类对象列表中列出吗?

C# 为什么我们使用类名调用委托??为什么可以';它不在类对象列表中列出吗?,c#,delegates,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("Proc

请参见下面的示例

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);
    }
  }
这里委托记录器是在类测试中编写的。。。当我创建类测试的对象时,即obj。。。这里没有列出代理记录器,当尝试使用类名时,我能够获得记录器

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

当我创建类测试的对象时,即obj。。。这里没有列出代理记录器,当尝试使用类名时,我能够获得记录器

嵌套在另一个类型中的类型不是实例成员。即使关键字
static
没有应用于嵌套类型的声明,在某种意义上它仍然是“静态的”。(虽然,在某种意义上,它不是一个运行时成员,您可以调用方法或访问字段或属性,所以我不确定我是否真的认为它是一个静态成员)。 更基本地说,委托类型
Logger
在任何方面都不是类的每个实例成员。即,每个实例不能有不同的
记录器
。因此,通过实例引用访问
Logger
类型没有任何意义

对于不是每个实例的类的任何成员,您可以使用类型名来访问它。例如,
测试记录器

如果委托类型在某种程度上是
Test
所独有的,并且与
Test
的公共API紧密关联,那么嵌套类型在这里可能有意义。也就是说,我倾向于避免使用公共嵌套类型,只有在看起来确实非常正确的时候才使用它们,主要是因为这个特定的问题。我不喜欢使用包含类型名的高质量类型名。:)

您确实有一些选择:

  • 甚至不要声明自定义委托类型。只需使用一个预定义的。在您的示例中,
    Action
    也同样有效
  • 不要嵌套类型。然后只需要使用名称空间限定它,当然可以使用
    语句通过
    使其隐式化
  • 为类型添加别名。例如,您可以使用Logger=MyNamespace.Test.Logger编写
    位于源代码文件顶部,您希望在其中使用该类型,然后您可以将其与较短的
    记录器一起使用。(当然,将
    MyNamespace
    替换为该类型的实际完全限定命名空间)

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

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

您可以在不使用测试类前缀的情况下访问记录器类型。部分原因是我们经常将委托视为嵌套类型,我们没有意识到它是一种类型,并且可以在名称空间中独立存在

因此,如果我理解正确,您的意思是问为什么必须调用
new Test.Logger(LogMe)
,而不仅仅是
new Logger(LogMe)
?@lonewolf我想是的-bakshay:这和嵌套类一样-如果你不想要这种行为,那么就把委托移到类之外。@lonewolf和@CarstenKonig根据我的说法,bakshay在问为什么
obj.Logger
即使是在测试类中也不会出现。更正Sandeep。。我想知道为什么我找不到obj.Logger…@bakshay:我想Peter Duniho已经回答了你的疑问,请过目一下。