Можете ли вы расширить общий класс в С#

Допустим, у меня есть этот класс

public Holder<T> : IHolder
{
    private mystring;
    private myobj;

    public Holder(T obj, string str)
    {
        mystring = str;
        myobj = obj;
    }
}

Затем я хочу, чтобы Holder‹ T> расширил T, чтобы я мог использовать Holder‹ T> как обычный T. Есть ли способ сделать это?

Так, например, я хотел бы, чтобы Holder‹ int> рассматривался как int.

Просто добавление : T не работает, но мне было любопытно, есть ли другой способ.

Неявные преобразования не будут работать, так как я хотел бы, чтобы они могли войти, например, IEnumerable‹ int>


person Anders Miltner    schedule 31.10.2013    source источник
comment
Попробуйте и посмотрите (это около 3 нажатий клавиш и будет работать или приведет к соответствующему сообщению об ошибке). Однако, возможно, сработает неявное преобразование в T?   -  person user2864740    schedule 31.10.2013
comment
Что ты имеешь в виду Продлить Т? Наследовать это?   -  person gunr2171    schedule 31.10.2013
comment
Итак, вы хотите, чтобы Holder‹int› рассматривался как int (например)?   -  person David Pilkington    schedule 31.10.2013
comment
Я думаю, что если это интерфейс, он будет работать нормально.   -  person Alexandre    schedule 31.10.2013
comment
Вы не можете сделать class Holder<T> : T   -  person Meirion Hughes    schedule 31.10.2013
comment
Не знаю, это то, что вам нужно, но попробуйте неявные преобразования для класса, но это может быть сложно сделать с универсальным типом.   -  person gunr2171    schedule 31.10.2013
comment
Это работает на C++, поэтому, вероятно, на C# так class Foo<T> : T   -  person 56ka    schedule 31.10.2013
comment
Какие отношения существуют между Холдером и Т.? Has a или is a?   -  person Hossein Narimani Rad    schedule 31.10.2013
comment
Ответьте здесь: stackoverflow.com/questions/1842636/   -  person 56ka    schedule 31.10.2013
comment
@ 56ka Шаблоны C++ сильно отличаются от универсальных шаблонов C#. Шаблоны C++ заменяют тип во время компиляции, в то время как дженерики C# делают это во время выполнения. Это может показаться тонким, но позволяет вам делать больше вещей с шаблонами C++ (поскольку они построены для определенных типов), что невозможно с универсальными шаблонами, поскольку они должны работать с любым типом, который удовлетворяет общим ограничениям.   -  person D Stanley    schedule 31.10.2013


Ответы (1)


Способ реализации дженериков в .NET требует, чтобы все Foo<T> вели себя практически одинаково независимо от T. Помимо прочего, все Foo<T> должны иметь одни и те же члены, за исключением того факта, что члены могут включать T в свои определения. Если бы Foo<T> мог наследовать от T, знание того, какие члены Foo<T> выставлялись, требовало бы знания того, какие выставлялись T члены, которые, конечно, могли бы быть совершенно разными для Foo<Automobile> и Foo<Cat>. Если кто-то знает, что Foo<T> будет использоваться только для типов, которые происходят, например, от. Animal, можно определить class Foo<T> : Animal where T:Animal, но это позволит использовать Foo<Cat> только как Animal, а не как Cat.

Однако во многих случаях действительно нужен не тип Foo<T>, который на самом деле наследует T, а скорее возможность создать объект, который в основном ведет себя как T, но с некоторыми отличиями. .NET Framework также не позволяет делать это напрямую, но есть некоторые библиотеки, которые могут автоматически генерировать прокси-объекты для этой цели. При заданном интерфейсе и одном или нескольких объектах, каждый из которых реализует некоторые члены интерфейса и которые в совокупности реализуют их все, генератор прокси создаст (во время выполнения!) новый класс, который содержит ссылки на предоставленные объекты и реализует этот интерфейс. путем создания для каждого метода интерфейса метода класса, который привязывается к соответствующему методу одного из переданных объектов.

Обратите внимание, что хотя метод, создающий эти новые классы, будет универсальным, сами классы таковыми не будут. Возможно, myProxyMaker.Create<IFoo>(IFlyingMammal) возвращает proxy8675309, а myProxyMaker.Create<ISwimmingMammal> возвращает proxy24601. Поскольку это совершенно разные классы, тот факт, что IFlyingMammal состоит из членов, отличных от ISwimmingMammal, не будет проблемой. Тот факт, что классы могут иметь уродливые имена, сгенерированные машиной, не имеет большого значения, поскольку объявляются не переменные типа proxy8675309 или proxy24601, а вместо этого типы IFlyingMammal и ISwimmingMammal.

person supercat    schedule 31.10.2013