在嵌套类中使用C#泛型

6

考虑以下类结构:

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,则会调用基本实现。


你如何在 Bar 中使用 U?使用 Foo<T> 不就足够了吗? - svick
在我看来,你现在正在做的是最好的事情。 - Saeed Amiri
Foo<T>不足以满足我的需求,因为我可能已经重写了FooBaz中的某些方法。如果Bar只是引用Foo<T>,那么它将使用Foo<T>中的基本实现。 - Matt Johnson-Pint
如果你重写了方法,那意味着你也有一个 Foo<T> 的实例,这意味着使用 Foo<T> 作为类型应该可以工作。如果 FooBaz 重写了一些方法,那么这些方法将被调用。这就是虚方法的工作原理。 - svick
如果你说“new Foo<T>()”,并不意味着你会自动得到一个FooBaz,即使已经定义了一个。我会更新问题并提供一些方法,这样你就可以看到。 - Matt Johnson-Pint
3个回答

3
如果 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();

当然,这些都是抽象的,可能或者不可能适用于实际例子。您在这里究竟想要达到什么目的?

当在容器类中U没有用处时,为什么要将其作为通用参数传递? - Saeed Amiri
@SaeedAmiri:因为它可能有用(我添加了类型为TU的字段以提示这一点)。 你怎么知道它不是有用的呢? - Jon
好的,这个可能有效,但我不确定FooBaz定义中递归的情况。我会试一下。 - Matt Johnson-Pint
好的,这确实有效。但这只是将冗余类型规范从子类移动到父类的权衡。我有比Bar更多的Foo,所以我想我会保持最初的方式。基本上,这个解决方案问的是同样的问题,但是针对的是SELF而不是PARENT。无论如何,还是谢谢。 - Matt Johnson-Pint
@Jon,如果它有用的话,OP应该将它们添加到容器类中,而不是你。我们只能评判我们所看到的。 - Saeed Amiri

2

不,你不能合并那个。

在 Foo 中,你有 T U,这是两种不同的类型,编译器无法为 U 创造一个类型,只能对其进行限制。


这就是我希望StackOverflow能让我选择两个被接受的答案的地方。这确实是真的。尽管Jon的回答有更多的细节,还是谢谢了。 - Matt Johnson-Pint

0

你为什么要引入U?在Bar的定义中,你不能用Foo<T>替代它吗?


不行。使用Foo<T>是不够的,因为我可能已经覆盖了FooBaz中的方法。如果Bar只是引用Foo<T>,它将使用Foo<T>中的基本实现。 - Matt Johnson-Pint
好的,这个问题在一开始并不清楚。因此我问为什么你引入了U。 - Frank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接