Seldah
Seldah

Reputation: 355

Return "this" of the subclass from superclass C#

I need to return "this" or the subclass instance from the superclass.

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();
    }
}

I have two Classes, class A is superclass and class B is the subclass inherited from A. those two classes implementing Interface A and B.

I need to call 'x.Format().PrintB();' just to format the string.

in other words, I need to return the same object in Format() function and based on the changes in the Format() I need to change the PrintB behavior.

so if I created new Class D and inherits A I want to Implement PrintD with different behavior based on isFormated as well.

Upvotes: 2

Views: 588

Answers (2)

Seldah
Seldah

Reputation: 355

I made A as a generic class take type T and I returned this as 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();
    }
}

Upvotes: 3

Scott Hannen
Scott Hannen

Reputation: 29252

When you call x.Next(), it returns an instance of something that implements IA. That could be A, B, or any other class that implements IA, but because it returns IA, other classes don't know what the concrete type is. That's usually intentional. If other classes don't know what the implementation of IA is then you can replace one with another.

However, since Next returns an IA, the only way you can call PrintB is if IA has a PrintB method, like this:

public interface IA
{
    void PrintB();
}

If A implements IA then it must have a PrintB method. But because it's an abstract class the method can be abstract. That means A doesn't really implement the method. A non-abstract class that inherits from A would be required to implement it.

That would look like this:

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

    public abstract void PrintB();
}

PrintB doesn't have to be abstract. A could implement it. It could be virtual and other classes could override it. Or it could be neither abstract nor virtual, and other classes couldn't override it.

Now, when you declare B : A, the compiler will require B to implement PrintB.

Then you can call Next().PrintB() because Next() returns IA and IA has a PrintB method.

Upvotes: 0

Related Questions