c# – Parameterized class. Returning a child class

Question:

I know it can't be done, but I'll ask anyway…

I have a base abstract class Control, where the parameter T is also some kind of Component class, but this is not so important.

I'm creating a Button child that inherits from Control.

public class MyButton : Control<SomeComponent>

I have methods in the base class, they do something and return a reference to themselves. It is convenient to do:

new MyButton().Text("Foo").Name("Boo")

But the problem is, I can only return Control in the base class. As a result, I get:

// 1.
MyButton btn = new MyButton();
btn.Text("");

// 2.
Control<Button> btn = new MyButton().Text("");

And I would like that in the case of option 2, MyButton was also returned.

Answer:

Normally this is not supported. But there is a crutch that works on single-level hierarchies:

class Control<TComponent, TSelf>
    where TSelf : Control<TComponent, TSelf>
{
    public virtual TSelf Foo () { return (TSelf)this; }
    // ...
}

class Button : Control<Object, Button>
{
    public override Button Foo () { return this; }
    // ...
}

If there is something else below the button in the hierarchy, then the crutch no longer works, unfortunately.

Alternatively, you can always override methods with new :

class Control<TComponent>
{
    protected virtual Control<TComponent> FooImpl () { return this; }
    public Control<TComponent> Foo () { return FooImpl(); }
    // ...
}

class Button : Control<Object>
{
    protected override Control<Object> FooImpl () { return this; }
    public new Button Foo () { return (Button)FooImpl(); }
    // ...
}

class SuperButton : Button
{
    protected override Control<Object> FooImpl () { return this; }
    public new SuperButton Foo () { return (SuperButton)FooImpl(); }
    // ...
}

There is more code, but the hierarchy can be of any depth.

There is also an option with interfaces, but it is even more verbose.

Scroll to Top