簡體   English   中英

為什么泛型類型參數與其他成員之間發生名稱沖突

[英]Why is there a name clash between generic type parameter and other members

有時,類似以下內容會很有用:

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 { ... }
  }
}

所以里面的東西知道什么是類型,什么是會員名

可能的答案:

在編寫非泛型版本時,您可能無法控制X類的名稱,並且人們可能希望將您的屬性稱為X ,因此您可能沒有選擇

在編寫通用版本時, 沒有人真正在乎您所謂的type參數 ,因此您可以通過選擇另一個名稱來解決此問題。

Ergo在編寫新的通用編譯器內容時,團隊進行了“我們可以使我們的編譯器能夠弄清楚什么時候他表示類型參數T和什么時候表示屬性T ,但這並不是真正必要的,因為他可以解決它。 ,所以讓我們把時間花在更有生產力的事情上。”

(然后VS團隊進行了“該死,編譯器團隊為此感到難受,現在我們需要弄清楚當用戶發現無法編譯時如何讓用戶重構它”)。

我認為錯誤消息中還存在另一種可能性:

類型“ Z”已經包含“ T”的定義。

任何單一類型都只能定義一次唯一命名的標識符(除了重載的方法,因為它們也有參數)。

在第一個示例中, X (類型) 由類Y定義; 它在外面定義。 X (屬性) 通過類定義Y

Z<T>第二個示例中, T (類型)由類Z定義,而T (屬性) 由類Z定義。 編譯器意識到它正在為一個類創建兩個相同名稱的標識符,舉起手來說:“不!不!不!!”

(然后,正如@Rawling指出的那樣,VS IDE團隊陷入了這個壞消息。)

類型和名稱之間有區別。 當您不知道(當時還是在編寫代碼)函數T時,如何編寫對函數T的調用?

編輯:上面的答案是錯誤地假定預期的行為是屬性名稱將隨T的類型而變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM