10

有时有类似的东西很有用:

class X {
  ...
}

class Y {
  X X {
    get { ... }
    set { ... }
  }
}

因为 X 描述了类型是什么(作为类名)和被访问/变异的值(作为属性名)。到现在为止还挺好。假设你想做同样的事情,但是以一种通用的方式:

class Z<T> {
  T T {
    get { ... }
    set { ... }
  }
}

对于这个例子,编译器抱怨:The type 'Z<T>' already contains a definition for 'T'.

属性、变量和方法都会发生这种情况,我不太明白为什么——编译器肯定知道 T 是一种类型,因此可以像第一个示例中那样找出它吗?

简短版本:为什么第一个示例有效,而第二个示例无效?

编辑:我刚刚发现,如果我“重构 > 重命名”类型参数,比如从 T 到 U,IDE 会将其更改为:

class Z<U> {
  U T {
    get { ... }
    set { ... }
  }
}

所以里面的东西知道什么是类型,什么是成员名

4

3 回答 3

4

可能的答案:

在编写非泛型版本时,您可能无法控制 class 的名称X,人们可能希望您的属性被调用X,因此您可能别无选择

当您编写通用版本时,没有人真正关心您所称的类型参数,因此您只需选择另一个名称即可解决此问题。

因此,在编写新的通用编译器的东西时,团队说“我们可以让我们的编译器能够弄清楚他什么时候表示类型参数-T以及什么时候表示属性T-,但这并不是真正必要的,因为他可以解决它,所以让我们把时间花在更有成效的事情上。”

(然后 VS 团队说“该死,编译器团队已经让我们背负了这个问题,现在我们需要弄清楚当用户发现它无法编译时如何让他重构它”......)

于 2012-10-19T10:30:24.747 回答
3

我认为另一种可能性在于错误消息:

“Z”类型已经包含“T”的定义。

任何单一类型都可能只能定义一次唯一命名的标识符(重载方法除外,因为它们也有参数)。

在第一个示例中X(类型)不是由 class 定义的Y;它是在外面定义的。而X(property)class 定义Y

在您的第二个示例中Z<T>T(type) 由 class 定义ZT(property)由 class 定义Z。编译器意识到它正在为一个类创建两个同名的标识符,举起手说:“不!不!不!”

(然后正如@Rawling 指出的那样,VS IDE 团队被这个坏消息困住了。)

于 2012-10-19T10:59:26.333 回答
0

类型和名称之间是有区别的。当您不知道(当时或编写代码)调用函数 T 时,您将如何编写对函数 T 的调用?

编辑:上面的答案错误地假设预期的行为是属性名称会随着 T 的类型而变化。

于 2012-10-19T10:22:12.610 回答