有时会有类似的东西:
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是一个类型,因此可以用与第一个示例相同的方式来计算它?
简短版本:为什么第一个示例有效,但不是第二个?
编辑:我刚刚发现,如果我“重构&gt;重命名”类型参数,例如从T到U,IDE会将其更改为:
class Z<U> {
U T {
get { ... }
set { ... }
}
}
所以那里的东西知道什么是类型,什么是成员名称
答案 0 :(得分:4)
可能的答案:
当您编写非通用版本时,您可能无法控制类X
的名称,并且人们可能希望您的属性被称为X
,因此您可能没有选择。
当您编写通用版本时,没有人真正关心您所谓的类型参数,因此您只需选择其他名称即可解决此问题。
Ergo,在编写新的通用编译器时,团队开始“我们可以让我们的编译器能够弄清楚何时他的意思是类型参数 - T
”当他意味着属性 - T
,但这并不是必要的,因为他可以解决它,所以让我们把时间花在更高效的事情上。“
(然后VS团队去了“该死的,编译器团队已经为此烦恼了,现在我们需要弄清楚如何让用户在发现它无法编译时重构这个”...)< / p>
答案 1 :(得分:3)
我认为另一种可能性在于错误消息:
“Z”类型已包含“T”的定义。
任何一种类型都可能只定义一次唯一命名的标识符(除了重载方法,因为它们也有参数)。
在第一个示例中,X
(类型)是由类Y
定义的不;它是在外面定义的。而X
(属性)是由类Y
定义的。
在Z<T>
的第二个示例中,T
(类型)由类Z
定义,T
(属性)也定义在班级Z
。编译器认识到它正在为一个类创建两个相同名称的标识符,然后举起手来说:“不!不!不!”
(然后正如@Rawling指出的那样,VS IDE团队陷入了坏消息。)
答案 2 :(得分:0)
类型和名称之间存在差异。当你不知道(当时或编写代码)它被称为什么时,你会怎么写函数T?
编辑:上述答案错误地假设预期的行为是属性名称会随着T的类型而变化。