Вызвать необобщенную функцию обобщенного класса

172
31 января 2019, 11:50

Допустим, есть класс MyClass<T>. В этом классе есть метод Common().

В переменной container типа object у меня могут хранится, к примеру, объекты типов MyClass<string>, MyClass<int> и MyClass<bool>.

Я хочу иметь доступ к функции Common в любом случае, но для этого мне надо привести объект к конкретному типу.

Я могу создать интерфейс, предоставляющий доступ к этому методу, но можно ли в таком случае как то сразу привести тип к общему шаблону ака "(MyClass<>)container"?

Просто у меня от MyClass<T> в будущем будет еще несколько дочерних обобщенных классов и для каждого так же писать новый интерфейс ради пары новых методов не очень удобно.

P.S. Ну еще можно вызвать метод через рефлексию, но это тоже такое себе решение...

Answer 1

Вам придется заводить базовый класс или интерфейс с методом Common(). Дело в том, что классы MyClass<string> и MyClass<int> не являются потомками/предками друг друга и у них нет никакого общего предка кроме object. Тут есть преимущество (ООП ради этого, собственно, и существует) — вам не потребуется приведение типов, container будет типизирован и вы сможете вызывать нужный метод прямо у него.

public interface ICommonable
{
    void Common();
}
public class MyClass<T> : ICommonable
{
    public void Common()
    {
        Console.WriteLine(typeof(T));
    }
}

Если вы не хотите заводить интерфейс из-за того, что его может реализовать какой-то сторонний класс, вы можете поступить следующим образом:

public abstract class Commonable
{
    internal Commonable() { }
    public abstract void Common();
}
public sealed class MyClass<T> : Commonable
{
    public override void Common()
    {
        Console.WriteLine(typeof(T));
    }
}

(см. этот ответ про модификаторы доступа), т. е. после того, как вы предоставите сборку с этими классами клиенту, он сможет создавать только экземпляры MyClass<T>, но не сможет создать другой класс, реализующий Commonable.

Варианты решения с использованием рефлексии или DRL тут я не рассматриваю, т. к. это уже не настоящее ООП и статическая типизация и к ним следует прибегать только в крайнем случае, когда других решений не существует (+ они несут дополнительные накладные расходы).

в будущем будет еще несколько дочерних обобщенных классов и для каждого так же писать новый интерфейс ради пары новых методов не очень удобно. — добро пожаловать в реальный мир, который не совсем похож на картинку с рекламного буклета :)

READ ALSO
Linq фильтрация результата

Linq фильтрация результата

Столкнулся с проблемой делаю запрос к БД

182
Как собрать сборку Chromium (CEF) с видео кодеками? [закрыт]

Как собрать сборку Chromium (CEF) с видео кодеками? [закрыт]

подскажите пожалуйста, как собрать сборку Chromium с видео кодекам? интересует воспроизведение видео в программе где будет использоваться Chromiumнужен...

180
c# WinForms UserControl утечка памяти

c# WinForms UserControl утечка памяти

друзьяРазрабатываю масштабный проект на c# WinForms, столкнулся с проблемой утечки памяти

160
Как в WPF в Textbox обойти string.Empty?

Как в WPF в Textbox обойти string.Empty?

Есть некоторая форма (её часть):

161