Вернуть «это» подкласса из суперкласса C # - PullRequest
1 голос
/ 02 апреля 2019

Мне нужно вернуть «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 и унаследовал AI, я хочу реализовать PrintD с другим поведением, также основанным на isFormated.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Я сделал 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();
    }
}
0 голосов
/ 02 апреля 2019

Когда вы вызываете x.Next(), он возвращает экземпляр чего-то, что реализует IA.Это может быть A, B или любой другой класс, который реализует 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...