如何确定哪个继承类正在使用抽象类的方法

时间:2010-04-18 08:58:58

标签: c# oop inheritance abstract-class

在我的控制台应用程序中有一个抽象的Factory类“Listener”,其中包含用于侦听和接受连接以及生成客户端类的代码。此类由另外两个类(WorldListener和MasterListener)继承,这些类包含更多特定于协议的覆盖和函数。

我还有一个帮助器类(ConsoleWrapper),它封装并扩展了System.Console,其中包含用于向WorldListener和MasterListener实例的内容写入控制台信息的方法。

我需要一种方法来在抽象的ListenerClass中确定哪个Inheriting类正在调用它的方法。

对此问题的任何帮助将不胜感激!我很难过: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 个答案:

答案 0 :(得分: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.

然而,你应该小心这种方法;它通常表明你需要明确检查类型的糟糕设计(因为这些lovely people坚持)。相反,使用多态来将所需行为委托给基类(使用基类中的虚拟或抽象方法)几乎总是更合适 - 毕竟,这就是它的设计目的!

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

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本身。

答案 1 :(得分: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!");
    }
}

答案 2 :(得分:2)

您可以使用

if (this is WorldListener)

而不是你的伪代码

if (inheriting class == WorldListener) 

然而,这样做是一种糟糕的设计气味。您应该强烈考虑替代解决方案,例如在虚方法中执行对控制台包装器的写操作,而不是在基类及其子类之间添加这种强耦合。