Использование обобщений c # во вложенном классе - PullRequest
6 голосов
/ 28 октября 2011

Рассмотрим следующую структуру класса:

public class Foo<T>
{
    public virtual void DoSomething()
    {
    }

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

public class Baz
{
}

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

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

var x = new FooBaz.Bar<FooBaz>();

Кажется излишним указывать его дважды. Как бы я создал структуру своего класса так, чтобы я мог сделать это вместо:

var x = new FooBaz.Bar();

Разве в предложении where вложенного класса не должно быть никакого способа сказать, что U всегда является родителем? Как?


Обновление: добавлены методы для DoSomething () выше, чтобы ответить на некоторые комментарии. Важно, что когда я вызываю DoSomething, он обращается к переопределенной версии. Если я просто использую Foo вместо U, то вместо этого вызывается базовая реализация.

Ответы [ 3 ]

3 голосов
/ 28 октября 2011

Если class Bar не должен быть универсальным, почему вы делаете его единым?

Это будет работать:

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

public class Baz
{
}

public class FooBaz : Foo<Baz, FooBaz>
{
}

А затем

var bar = new FooBaz.Bar();

Конечно, все это абсолютно абстрактно, так что это может или не может применяться к практическому примеру.Что именно вы пытаетесь достичь здесь?

2 голосов
/ 28 октября 2011

Нет, вы не можете объединить это.

Внутри Foo у вас есть T и U, 2 разных типа, и компилятор не может создать тип для U, только ограничить его.

0 голосов
/ 28 октября 2011

Почему вы вообще вводите U? Разве вы не можете заменить его использование везде в определении Bar на Foo<T>?

...