Страницы

Поиск по вопросам

воскресенье, 12 января 2020 г.

Параметризованный класc. Возврат класса потомка

#c_sharp


Я так понимаю это сделать нельзя, но всё таки спрошу...

Есть у меня базовый абстрактный класс Control, где параметр T - это тоже какой-то
класс Component, но это уже не так важно.

Я создаю потомка Button - наследник от Control.

public class MyButton : Control


В базовом классе у меня есть методы, они что-то делают и возвращают ссылку на самого
себя. Бывает удобно сделать:

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


Но проблема в том, я могу вернуть только Control в базовом классе.
В итоге у меня получается:

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

// 2.
Control


Ответы

Ответ 1



Нормально это не поддерживается. Но есть костыль, который работает на одноуровневых иерархиях: class Control where TSelf : Control { public virtual TSelf Foo () { return (TSelf)this; } // ... } class Button : Control { public override Button Foo () { return this; } // ... } Если ниже кнопки по иерархии есть что-то ещё, то костыль уже не работает, к сожалению. Как вариант, можете всегда перекрывать методы с помощью new: class Control { protected virtual Control FooImpl () { return this; } public Control Foo () { return FooImpl(); } // ... } class Button : Control { protected override Control FooImpl () { return this; } public new Button Foo () { return (Button)FooImpl(); } // ... } class SuperButton : Button { protected override Control FooImpl () { return this; } public new SuperButton Foo () { return (SuperButton)FooImpl(); } // ... } Кода больше, но иерархия может быть любой глубины. Также есть вариант с интерфейсами, но он ещё многословнее.

Комментариев нет:

Отправить комментарий