【问题标题】:Return "this" of the subclass from superclass C#从超类 C# 返回子类的“this”
【发布时间】:2019-04-02 15:40:34
【问题描述】:

我需要从超类返回“this”或子类实例。

interface IA
{
    IA Format();
    void Print();
}
interface IB
{
    IA Format();
    void Print();
    void PrintB();
}
abstract class A : IA
{
    protected bool isFormated;
    public IA Format()
    {
        isFormated = true; 
        return this;
    }
    virtual public void Print()
    {
        Console.WriteLine("this is A");
    }
}

class B : A, IB
{
    override public void Print()
    {
        Console.WriteLine("this is B");
    }
    public void PrintB()
    {
        if (isFormated)
        {
            Console.WriteLine("this is formated B");
        }
        else
        {
            Console.WriteLine("this is B");
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        var x = new B();
        x.Format().PrintB();
    }
}

我有两个类,A 类是超类,B 类是从 A 继承的子类。 这两个类实现了接口 A 和 B。

我需要调用'x.Format().PrintB();'只是为了格式化字符串。

换句话说,我需要在 Format() 函数中返回相同的对象,并且基于 Format() 中的更改,我需要更改 PrintB 行为。

因此,如果我创建了新的 D 类并继承了 A,我也想基于 isFormated 实现具有不同行为的 PrintD。

【问题讨论】:

  • 您正在返回 B 的实例 - 这里只有一个实例在起作用 - 但输入为 IA 所以它没有 PrintB 方法。你能详细解释一下你真正想要实现的目标吗?
  • 我正在尝试返回 B 的“this”,但我的代码中缺少某些内容。我也应该在子类中实现“Next()”吗?
  • IAIB之间有关系吗?
  • 当您已经将实例存储在x 中时,为什么还需要使用this
  • @Svarr 我有这方面的用例,但我试图让这个例子变得简单。

标签: c# oop


【解决方案1】:

我将 A 作为泛型类采用 T 类型并将其返回为 T

    interface IA<T> where T : class
{
    T Format { get; }
    void Print();
}
abstract class A<T> : IA<T> where T : class
{
    protected bool isFormated;
    public T Format
    {
        get
        {
            isFormated = true;
            return this as T;
        }
    }

    virtual public void Print()
    {
        Console.WriteLine("this is A");
    }
}

interface IB
{
    void Print();
    void PrintB();
}
class B : A<B>, IB
{
    override public void Print()
    {
        Console.WriteLine("this is B");
    }
    public void PrintB()
    {
        if (isFormated)
        {
            Console.WriteLine("this is formated B");
        }
        else
        {
            Console.WriteLine("this is B");
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        var x = new B();
        x.Format.PrintB();
    }
}

【讨论】:

    【解决方案2】:

    当您调用x.Next() 时,它会返回一个实现IA 的实例。那可能是AB,或任何其他实现IA 的类,但因为它返回IA,其他类不知道具体类型是什么。这通常是故意的。如果其他类不知道IA 的实现是什么,那么您可以将一个替换为另一个。

    但是,由于Next 返回一个IA,你可以调用PrintB 的唯一方法是IA 有一个PrintB 方法,像这样:

    public interface IA
    {
        void PrintB();
    }
    

    如果A 实现了IA,那么它必须有一个PrintB 方法。但是因为它是一个abstract 类,所以该方法可以是抽象的。这意味着A 并没有真正实现该方法。实现它需要一个继承自A 的非抽象类。

    看起来像这样:

    abstract class A : IA
    {
        public IA Next()
        {
            return this;
        }
        virtual public void Print()
        {
            Console.WriteLine("this is A");
        }
    
        public abstract void PrintB();
    }
    

    PrintB 不必是抽象的。 A 可以实现它。它可以是虚拟的,其他类可以覆盖它。或者它既不是抽象的也不是虚拟的,其他类不能覆盖它。

    现在,当您声明 B : A 时,编译器将要求 B 实现 PrintB

    然后你可以调用Next().PrintB(),因为Next()返回IA并且IA有一个PrintB方法。

    【讨论】:

    • 感谢您的回答,我已经更新了问题并更改了示例。情况是我需要在 Format() 函数中返回相同的对象,并且基于 Format() 中的更改,我需要更改 PrintB 行为。所以如果我创建了新的 D 类并继承了 A 我想实现 PrintD
    • 看起来您已经完成了大部分任务。几点建议。如果您确实需要这两个接口,也许可以从另一个继承。这样IB 只声明了一个新方法,而不是IA 中的所有相同方法。接下来,我想知道x.Format().PrintB(); 带来了多少复杂性
    • 只是事后的想法 - 没什么大不了的 - 如果您使用稍微大一点的类名,它会有所帮助。在现实生活中,它们往往不止一个字母,因此 AB 看起来可能有点令人困惑。这就是为什么很多人使用 Foo 和 Bar、Car 和 Truck 或其他什么的原因。
    • 对此我很抱歉,我尽量使示例简单。但是,我已经找到了解决方案,请检查更新。
    猜你喜欢
    • 2013-10-17
    • 1970-01-01
    • 2011-04-05
    • 2015-03-09
    • 2018-12-28
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 2018-05-09
    相关资源
    最近更新 更多