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 が型であることを認識しているため、最初の例と同じ方法でそれを理解できるのでしょうか?

短いバージョン:最初の例は機能するのに、2 番目の例は機能しないのはなぜですか?

編集:型パラメーターを「リファクタリング > 名前の変更」すると、たとえば T から U に変更すると、IDE によって次のように変更されることがわかりました。

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

その中の何かが、何が型で何がメンバー名かを知っています

4

3 に答える 3

4

可能な答え:

非ジェネリック バージョンを作成している場合、おそらく class の名前を制御することはできずX、人々はあなたのプロパティが呼び出されることを期待する可能性があるため、選択Xの余地がない可能性があります。

ジェネリック バージョンを書いているときは、型パラメーターの名前を気にする人はいないので、別の名前を選択するだけでこれを回避できます。

そのため、新しい汎用コンパイラーを作成する際に、チームは「コンパイラーTが type-parameter- を意味するときと、property- を意味するときを理解できるようにすることができましたTが、回避できるため、実際には必要ありません。代わりに、もっと生産的なことに時間を使いましょう。」

(そしてVSチームはその後、「くそー、コンパイラチームはこれを私たちに課しました。今、ユーザーがコンパイルできないことがわかったときにこれをリファクタリングできるようにする方法を理解する必要があります」...)

于 2012-10-19T10:30:24.747 に答える
3

私が考える別の可能性は、エラーメッセージにありました:

タイプ「Z」には、「T」の定義がすでに含まれています。

単一のタイプは、一意に名前が付けられた識別子を 1 回しか定義できない可能性があります (オーバーロードされたメソッドは別として、パラメーターもあるからです)。

最初の例X(type) はclass によって定義されていませんY。外部で定義されています。一方X、 (プロパティ)class によって定義されYます。

の2番目の例ではZ<T>T(type) は class によって定義されZT(property)class によって定義されていZます。コンパイラは、1 つのクラスに対して同じ名前の 2 つの識別子を作成していることを認識し、手を上げて、「ダメ! ダメ! ダメ!」と言います。

(その後、@Rawling が指摘するように、VS IDE チームは悪いニュースに行き詰まりました。)

于 2012-10-19T10:59:26.333 に答える
0

種類と名前は違います。関数 T の呼び出しを (その時点またはコードを書いているときに) 知らなかった場合、関数 T の呼び出しをどのように記述しますか?

編集: 上記の回答は、プロパティ名が T の型によって異なることを意図した動作であると誤って想定していました。

于 2012-10-19T10:22:12.610 に答える