Використання загальних засобів c # у вставленому класі

Розглянемо наступну структуру класу:

public class Foo
{
    public virtual void DoSomething()
    {
    }

    public class Bar where U : Foo, new()
    {
        public void Test()
        {
            var blah = new U();
            blah.DoSomething();
        }
    }
}

public class Baz
{
}

public class FooBaz : Foo
{
    public override void DoSomething()
    {
    }
}

Коли я йду використовувати вкладене клас, у мене є щось на зразок наступного:

var x = new FooBaz.Bar();

Здається зайвим, що треба вказати його двічі. Як мені створити структуру класу так, щоб я міг це зробити замість цього:

var x = new FooBaz.Bar();

Чи не повинно бути якимось чином, в якому місці вкладеного класу сказати, що U завжди є батьком? Як?


Оновлення: Додані методи для DoSomething() вище для вирішення деяких коментарів. Важливо, що, коли я називаю DoSomething, він звертається до виключеної версії. Якщо я просто використовую Foo замість U, то замість нього запускається базова реалізація.

6
Foo не вистачає, тому що я можу переопределити методи в FooBaz. Якщо в панелі просто називається Foo , він використовує базову реалізацію в Foo .
додано Автор Matt Johnson, джерело
Якщо ви кажете "новий Foo ()", ви автоматично не отримуєте FooBaz лише тому, що його визначено. Я оновлю питання з деякими методами, щоб ви могли побачити.
додано Автор Matt Johnson, джерело
IMO Найкраще, що ви можете зробити, це те, що ви зараз робите.
додано Автор Saeed Amiri, джерело
Як ви використовуєте U всередині Bar ? Чи не буде достатньо використовувати Foo ?
додано Автор svick, джерело
Якщо у вас є переопределені методи, це означає, що ви також маєте примірник Foo , а це означає, що використовується Foo , оскільки тип повинен працювати. Якщо FooBaz перевизначає деякі методи, це ті, які будуть викликані. Так працюють віртуальні методи.
додано Автор svick, джерело

3 Відповіді

Якщо клас Bar не повинні бути універсальними, чому ви робите це один?

Це буде працювати:

public class Foo where U : Foo
{     
    public class Bar
    {
        private T t;
        private U u;
    }
}

public class Baz
{
}

public class FooBaz : Foo
{
}

І потім

var bar = new FooBaz.Bar();

Звичайно, все це абсолютно абстрактно, тому воно могло б або не застосовуватися до практичного прикладу. Що саме ви намагаєтеся досягти тут?

3
додано
Гаразд, це може працювати, але я не впевнений в тому, що відбувається рекурсія у визначенні FooBaz. Я спробую це.
додано Автор Matt Johnson, джерело
Гаразд, це дійсно працює. Але це просто компроміс переміщення специфікації резервного типу до батьківського класу замість дитини. У мене є багато більше Foo ніж Бар, так що я думаю, я залишу це, як я спочатку показав. По суті, це рішення задає одне і те ж питання, а не SELF, а не PARENT. Все одно, дякую.
додано Автор Matt Johnson, джерело
Коли U не є корисним у класі контейнерів, то чому передавати його як загальний параметр?
додано Автор Saeed Amiri, джерело
@Jon, якщо це корисно OP, слід додати їх у класі контейнерів, а не на вас. ми просто можемо судити про те, що ми можемо побачити
додано Автор Saeed Amiri, джерело
@SaeedAmiri: Тому що це може бути корисним (я додав поля типу T і U , щоб натякнути на це). Як ти знаєш, що це не так?
додано Автор Jon, джерело

Ні, ви не можете об'єднати це.

Всередині Foo у вас є T та U, 2 різних типів, і компілятор не може скласти тип для U, лише обмежує його.

2
додано
Саме тут я бажаю, щоб StackOverflow дозволило мені вибрати два прийнятих відповіді. Це дійсно так. Відповідь Джона трохи докладніше. Все одно, дякую.
додано Автор Matt Johnson, джерело

Why do you introduce U at all? Can you not replace its use everywhere within the definition of Bar with Foo?

0
додано
Знову ні. Використання Foo недостатньо, тому що я можу мати переопределені методи в FooBaz. Якщо в панелі просто називається Foo , він використовує базову реалізацію в Foo .
додано Автор Matt Johnson, джерело
Гаразд, це було не зрозуміло мені з першого питання. Звідси я запитав, чому ти ввів U.
додано Автор Frank, джерело
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug