如何确定哪个继承类正在使用抽象类的方法?涉及IT技术相关内容。

4
在我的控制台应用程序中,有一个抽象工厂类“Listener”,其中包含用于监听和接受连接以及生成客户端类的代码。该类被另外两个类(WorldListener和MasterListener)继承,这些类包含更多协议特定的重写和函数。
我还有一个辅助类(ConsoleWrapper),它封装并扩展了System.Console,包含用于向控制台写入关于WorldListener和MasterListener实例正在发生的信息的方法。
我需要一种方法在抽象ListenerClass中确定是哪个继承类调用了它的方法。
任何有关此问题的帮助都将不胜感激!我手足无措:X
下面是我试图做的事情的简化示例。
abstract class Listener
{
   public void DoSomething()
   {
      if(inheriting class == WorldListener)
      ConsoleWrapper.WorldWrite("Did something!");
      if(inheriting class == MasterListener)
      ConsoleWrapper.MasterWrite("Did something!");
   }
}

public static ConsoleWrapper
{
   public void WorldWrite(string input)
   {
       System.Console.WriteLine("[World] {0}", input);
   }
}

public class WorldListener : Listener
{
   public void DoSomethingSpecific()
   {
       ConsoleWrapper.WorldWrite("I did something specific!");
   }
}

public void Main()
{
   new WorldListener();
   new MasterListener();
}

期望输出

[世界] 做了些什么!
[世界] 我做了某件具体的事情!
[主人] 做了些什么!
[世界] 我做了某件具体的事情!

3个回答

4

如果您知道要与之比较的每种类型,则使用 is 运算符:

if (this is WorldListener)
{
 // ...
}
else if (this is MasterListener)
{
 // ...
}

如果您想要更灵活的方式,您可以使用GetType

var type = GetType();
// Do some logic on the type to determine what to do next.

然而,你需要小心这种方法;显式检查类型通常表明设计有问题(正如这些可爱的人们所坚持的那样)。相反,通常更适合使用多态性将所需行为委托给基类(在基类中使用虚拟或抽象方法)-毕竟,这就是它的设计初衷!

你可以像这样应用多态性:

static class Program
{
    static void Main(string[] args)
    {
        Listener listener = new WorldListener();
        listener.DoSomething();
    }
}

abstract class Listener
{
    public void DoSomething()
    {
        var output = Decorate("Did something!");
        ConsoleWrapper.WriteLine(output);
    }

    protected abstract string Decorate(string input);
}

class WorldListener : Listener
{
    protected override string Decorate(string input)
    {
        return string.Format("[World] {0}", input);
    }
}

class MasterListener : Listener
{
    protected override string Decorate(string input)
    {
        return string.Format("[Master] {0}", input);
    }
}

这将产生输出[World] Did something!。这种方法的优点在于,如果您想要添加另一种类型的监听器,只需为其定义一个新类,并使用适当的Decorate方法即可;不需要修改Listener本身。

非常好的答案,希望我可以选择多个! - Kin
听起来我对抽象方法的理解可能有缺陷,感谢您的帮助。 - Kin
@Kin:我修改了我之前给出的示例以进行演示。 - Will Vousden
更清晰了,谢谢。在重写方法中放置Console.WriteLine而不是基类中会有任何问题吗? - Kin
我不认为这样做有任何优势,而且会使它变得不太灵活。由于基类为所有具体监听器类提供了共同功能,因此将输出逻辑放在其中比放在子类中更有意义(除非可能某些监听器输出的方式不同,但这时你可以考虑创建一个抽象的“输出”方法)。记住DRY原则:http://en.wikipedia.org/wiki/DRY. - Will Vousden
显示剩余2条评论

2

嗯.. 在你的简化示例中,你没有调用DoSomething()和DoSomethingSpecific(),并且MasterListener也没有实现.. 此外,如果我理解正确,在你的预期输出中,MasterListener.DoSomethingSpecific()运行了ConsoleWrapper.WorldWrite.. 你可能是指MasterWrite?

无论如何.. 这里有一个可以实现你想要的功能的工作示例(至少按照我理解你的请求的方式 :P)

打印结果如下:

[World] Did something
[World] I did sth specific!
[Master] Did something
[Master] I did sth specific!

代码:

    void Main()
{
    var wl = new WorldListener();
    wl.DoSomething();
    wl.DoSpecific();
    var ml = new MasterListener();
    ml.DoSomething();
    ml.DoSpecific();
}

public abstract class Listener
{
    public abstract string Category { get; }
    public void DoSomething()
    {
        ConsoleWrapper.Write(Category, "Did something");
    }
}

public static class ConsoleWrapper
{
    public static void Write(string category, string input)
    {
        Console.WriteLine("[{0}] {1}", category, input);
    }
}

public class WorldListener : Listener
{
    public override string Category { get { return "World"; } }
    public void DoSpecific()
    {
        ConsoleWrapper.Write(Category, "I did sth specific!");
    }
}

public class MasterListener : Listener
{
    public override string Category { get { return "Master"; } }
    public void DoSpecific()
    {
        ConsoleWrapper.Write(Category, "I did sth specific!");
    }
}

我已经更新了这个示例,包含你可能需要的内容 - Listener类不依赖于子继承类。相反,子类必须实现一个Category属性,该属性将定义哪个类向ConsoleWrapper发送了字符串。 - Artiom Chilaru

2
您可以使用

标签


if (this is WorldListener)

使用实际的代码代替您的伪代码

if (inheriting class == WorldListener) 

然而,这样做是一种不好的设计方式。您应该强烈考虑替代方案,例如在虚拟方法中执行对控制台包装器的写入,而不是在基类和其子类之间添加这种强耦合。

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