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.