见下面的例子......
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列表中。
答案 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视为嵌套类型,因此我们没有意识到它是一种类型,并且可以在命名空间中独立存在。