248

他の人がこのキーワードをどのように使用しているかに興味がありました。私はコンストラクターで使用する傾向がありますが、他のメソッドのクラス全体で使用することもあります。いくつかの例:

コンストラクターで:

public Light(Vector v)
{
    this.dir = new Vector(v);
}

他の場所

public void SomeMethod()
{
    Vector vec = new Vector();
    double d = (vec * vec) - (this.radius * this.radius);
}
4

31 に答える 31

245

意地悪に聞こえるつもりはありませんが、問題ではありません。

真剣に。

プロジェクト、コード、仕事、私生活など、重要なことに注目してください。フィールドへのアクセスを制限するために「this」キーワードを使用するかどうかに依存する成功はありません。このキーワードは、時間通りに出荷するのに役立ちません。バグを減らすことにはなりませんし、コードの品質や保守性に大きな影響を与えることもありません。昇給もなければ、オフィスで過ごす時間を減らすこともできません。

それは本当にただのスタイルの問題です。「これ」が好きなら、それを使ってください。そうでない場合は、しないでください。正しいセマンティクスを得るために必要な場合は、それを使用してください。真実は、すべてのプログラマーが独自のプログラミング スタイルを持っているということです。そのスタイルは、「最も美しいコード」とはどのようなものであるべきかという特定のプログラマーの考えを反映しています。定義上、あなたのコードを読む他のプログラマーは、異なるプログラミング スタイルを持つことになります。つまり、あなたがしたことで相手が気に入らないことや、別のことをしていたであろうことが常にあるということです。ある時点で、誰かがあなたのコードを読んで、何かについて不平を言うでしょう。

私はそれについて心配しません。私は、あなたの好みに応じて、コードが可能な限り審美的に満足できるものであることを確認したいと思います. 10 人のプログラマーにコードのフォーマット方法を尋ねると、約 15 の異なる意見が返ってきます。注目すべきより良いことは、コードがどのように因数分解されるかです。物事は正しく抽象化されていますか? 物事に意味のある名前を付けましたか? コードの重複は多いですか?物事を単純化する方法はありますか?これらを正しく行うことは、プロジェクト、コード、仕事、そして人生に最大のプラスの影響を与えると思います。偶然にも、それはおそらく他の男の不平を最も少なくする原因にもなります. あなたのコードが機能し、読みやすく、適切に構成されている場合、他の人はフィールドの初期化方法を精査することはありません。彼はただあなたのコードを使い、その素晴らしさに驚嘆し、

于 2008-08-22T20:42:19.137 に答える
217

C# では、このキーワードの使用法がいくつかあります。

  1. 類似した名前で非表示になっているメンバーを修飾するには
  2. オブジェクト自身をパラメーターとして他のメソッドに渡すには
  3. オブジェクトがメソッドから自身を返すようにする
  4. インデクサーを宣言するには
  5. 拡張メソッドを宣言するには
  6. コンストラクター間でパラメーターを渡すには
  7. 値型 (構造体) value を内部的に再割り当てします
  8. 現在のインスタンスで拡張メソッドを呼び出すには
  9. 自分自身を別の型にキャストするには
  10. 同じクラスで定義されたコンストラクターをチェーンするには

スコープ内に同じ名前のメンバー変数とローカル変数を持たないようにすることで、最初の使用を避けることができます。たとえば、一般的な命名規則に従い、フィールド (キャメル ケース) の代わりにプロパティ (パスカル ケース) を使用して、ローカル変数 (キャメル ケースも) との衝突を回避します。場合)。C# 3.0 では、自動実装されたプロパティを使用して、フィールドを簡単にプロパティに変換できます。

于 2008-08-22T21:12:48.937 に答える
96

私は絶対に必要な場合、つまり別の変数が別の変数をシャドウイングしている場合にのみ使用します。ここのような:

class Vector3
{
    float x;
    float y;
    float z;

    public Vector3(float x, float y, float z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

}

または、Ryan Foxが指摘しているように、これをパラメーターとして渡す必要がある場合。(ローカル変数はメンバー変数よりも優先されます)

于 2008-08-22T19:26:06.900 に答える
54

個人的には、メンバー変数を参照するときは常にこれを使用するようにしています。コードを明確にし、読みやすくするのに役立ちます。あいまいさがなくても、私のコードを初めて読んだ人はそれを知りませんが、これが一貫して使用されているのを見れば、メンバー変数を見ているかどうかがわかります。

于 2008-08-23T05:05:44.557 に答える
38

必要がない場合でも、インスタンス変数を参照するたびに使用します。コードがより明確になると思います。

于 2008-08-22T19:22:48.623 に答える
36

常にそれを使用することが「ベストプラクティス」などであると言うすべての人が信じられません。

Coreyの例のようにあいまいな場合、またはRyanの例のようにオブジェクトをパラメーターとして渡す必要がある場合は、「this」を使用します。スコープチェーンに基づいて変数を解決できることは十分に明確であるため、それを使用して変数を修飾する必要がないため、他の方法で使用する理由はありません。

編集:「this」に関するC#ドキュメントは、「this」キーワードの、私が言及した2つに加えて、もう1つの使用法を示しています-インデクサーを宣言するため

編集:@Juan:ええと、ステートメントに矛盾は見られません。「this」キーワードを使用する場合は3つあり(C#ドキュメントに記載されています)、実際に必要な場合があります。シャドウイングが行われていないときにコンストラクターの変数の前に「これ」を貼り付けることは、単にキーストロークの無駄であり、それを読み取るときの私の時間の無駄であり、利点はありません。

于 2008-08-22T19:46:46.383 に答える
27

StyleCopが私に指示するときはいつでもそれを使用します。StyleCopに従う必要があります。そうそう。

于 2008-08-22T20:00:47.333 に答える
11

現在のオブジェクトへの参照が必要なときはいつでも。

特に便利なシナリオの1つは、オブジェクトが関数を呼び出していて、それ自体を関数に渡したい場合です。

例:

void onChange()
{
    screen.draw(this);
}
于 2008-08-22T19:26:37.430 に答える
7

私が扱っているのがインスタンスメンバーであることを明確にするために、私はどこでもそれを使用する傾向があります。

于 2008-08-22T19:31:26.560 に答える
5

this キーワードのもう 1 つのややまれな使用法は、実装クラス内から明示的なインターフェイス実装を呼び出す必要がある場合です。これは不自然な例です:

class Example : ICloneable
{
    private void CallClone()
    {
        object clone = ((ICloneable)this).Clone();
    }

    object ICloneable.Clone()
    {
        throw new NotImplementedException();
    }
}
于 2008-09-19T19:58:13.290 に答える
5

あいまいさがあるかもしれない場所ならどこでも使用します(明らかに)。コンパイラのあいまいさだけでなく (その場合は必要になります)、コードを見ている人にとってのあいまいさもあります。

于 2008-08-22T19:23:02.120 に答える
4

これが私がそれを使用するときです:

  • クラス内からのプライベート メソッドへのアクセス (区別するため)
  • 現在のオブジェクトを別のメソッドに (またはイベントの場合は送信側オブジェクトとして) 渡す
  • 拡張メソッドを作成するとき:D

プライベート フィールド変数名の前にアンダースコア (_) を付けているため、プライベート フィールドにはこれを使用しません。

于 2008-08-22T21:19:47.533 に答える
4

【C++】

「必要なときに使用する」旅団に同意します。これでコードを不必要に装飾するのは良い考えではありません。これは、これが常にそこにあることを期待している人々に潜在的な混乱をもたらします。つまり、彼らはそれについて考える必要があります.

では、いつ使うのでしょうか?いくつかのランダムなコードを調べたところ、これらの例が見つかりました (これらが良いことかそうでないかについては判断していません):

  • 「自分自身」を関数に渡す。
  • 「自分」をポインターなどに割り当てる。
  • キャスト、つまり、アップ/ダウン キャスト (安全かどうかに関係なく)、constness のキャストなど。
  • コンパイラによる曖昧さの解消。
于 2008-08-26T17:25:29.043 に答える
3

Jakub Šturc の回答では、コンストラクター間でのデータの受け渡しに関する彼の #5 で、おそらく少し説明を使用できます。これはコンストラクターのオーバーロードであり、の使用thisが必須の 1 つのケースです。次の例では、デフォルトのパラメーターを使用して、パラメーターなしのコンストラクターからパラメーター化されたコンストラクターを呼び出すことができます。

class MyClass {
    private int _x
    public MyClass() : this(5) {}
    public MyClass(int v) { _x = v;}
}

これは、場合によっては特に便利な機能であることがわかりました。

于 2008-09-19T19:58:30.887 に答える
3

常に使用する必要があります。プライベート フィールドとパラメーターを区別するために使用します (命名規則では、メンバー名とパラメーター名にプレフィックスを使用しないと規定されているためです (また、それらはインターネットで見つかった情報に基づいているため、ベストプラクティス))

于 2008-08-22T19:23:34.253 に答える
3

同じ型のオブジェクトへの参照を受け入れる関数で、どのオブジェクトをどこで参照しているかを完全に明確にしたい場合に使用します。

例えば

class AABB
{
  // ... members
  bool intersects( AABB other )
  {
    return other.left() < this->right() &&
           this->left() < other.right() &&

           // +y increases going down
           other.top() < this->bottom() &&
           this->top() < other.bottom() ;
  }
} ;

(対)

class AABB
{
  bool intersects( AABB other )
  {
    return other.left() < right() &&
           left() < other.right() &&

           // +y increases going down
           other.top() < bottom() &&
           top() < other.bottom() ;
  }
} ;

AABB はどの AABBright()を参照していますか? はthis、少し明確化を追加します。

于 2010-05-07T14:19:34.130 に答える
2

私は Visual C++ でこれを自由に使用する習慣を身につけました。これを行うと、'>' キーを押した IntelliSense がトリガーされてしまうため、怠け者です。(しかもタイプミスしやすい)

しかし、グローバル関数ではなくメンバー関数を呼び出していることが分かりやすいので、私はそれを使い続けています。

于 2008-08-26T02:00:07.817 に答える
1

[C ++]

これは、ほとんどの場合、次のような奇妙な(意図的でない、危険な、または単に時間の無駄)ことをチェックして防止する必要がある代入演算子で使用されます。

A a;
a = a;

代入演算子は次のように記述されます。

A& A::operator=(const A& a) {
    if (this == &a) return *this;

    // we know both sides of the = operator are different, do something...

    return *this;
}
于 2008-09-16T07:25:18.530 に答える
1

これは、同じ型の内部から型プロパティを参照する場合にのみ使用します。別のユーザーが述べたように、ローカルフィールドにも下線を付けて、これを必要とせずに目立つようにします。

于 2008-08-22T19:29:51.620 に答える
1

必要な場合にのみ使用しますが、単一引数のポリモーフィズムのために片側のメソッドに入れる必要がある対称操作を除きます。

boolean sameValue (SomeNum other) {
   return this.importantValue == other.importantValue;
} 
于 2008-09-06T11:50:15.717 に答える
1

thisC++ コンパイラで

C++ コンパイラは、シンボルがすぐに見つからない場合、黙ってシンボルを検索します。時々、ほとんどの場合、それは良いことです:

  • 子クラスでオーバーロードしていない場合は、マザー クラスのメソッドを使用します。
  • 型の値を別の型に昇格させる

しかし、コンパイラに推測させたくない場合もあります。コンパイラーが別のシンボルではなく、正しいシンボルをピックアップするようにします。

私にとっては、メソッド内で、メンバーメソッドまたはメンバー変数にアクセスしたいときです。printfの代わりに書いたからといって、ランダムなシンボルを拾いたくないだけですprintthis->printfコンパイルしなかったでしょう。

要点は、C のレガシー ライブラリ (§)、何年も前に書かれたレガシー コード (§§)、またはコピー/貼り付けが廃止されたがまだアクティブな機能である言語で発生する可能性のあるもので、コンパイラに再生しないように指示することがあります。ウィットは素晴らしいアイデアです。

これらが私が使用する理由ですthis

(§) それは私にはまだ一種の謎ですが、ソースに <windows.h> ヘッダーを含めているという事実が、すべてのレガシー C ライブラリ シンボルがグローバル名前空間を汚染する理由なのだろうかと今では思っています。

(§§) 「ヘッダーをインクルードする必要がありますが、このヘッダーをインクルードすると、一般的な名前のばかげたマクロを使用するため、コードが壊れる」という認識は、コーダーの人生におけるロシアン ルーレットの瞬間の 1 つです。

于 2008-09-19T19:47:04.173 に答える
1

私は _ でフィールドに下線を引く傾向があるので、実際にこれを使用する必要はありません。また、R#はとにかくそれらをリファクタリングする傾向があります...

于 2008-08-22T19:23:16.847 に答える
1

多くの開発者が同じコード ベースで作業している場合、いくつかのコード ガイドライン/ルールが必要です。私が働いている場所では、フィールド、プロパティ、およびイベントで「this」を使用することにしました。

クラス変数とメソッド変数を区別すると、コードが読みやすくなります。

于 2009-04-23T20:12:37.223 に答える
1

できる限り毎回使用しています。これによりコードが読みやすくなり、コードが読みやすくなればバグが減り、保守性が向上すると私は信じています。

于 2009-04-23T18:54:08.083 に答える
1

'これ。' 多くのメンバーを持つ「この」クラスのメンバーを見つけるのに役立ちます(通常、深い継承チェーンが原因です)。

CTRL+Space を押しても、タイプも含まれているため、これには役立ちません。ここで「これ」として。メンバーのみが含まれます。

私は通常、自分が求めていたものを手に入れたら削除しますが、これは私のスタイルの突破口です.

スタイルに関しては、もしあなたが孤独なレンジャーなら、あなたが決めてください。会社で働いている場合は、会社のポリシーに固執します (ソース管理の内容を見て、他の人が何をしているかを確認してください)。メンバーの資格を得るためにそれを使用するという点では、どちらが正しいか間違っているかはわかりません。唯一の間違いは矛盾です。それがスタイルの黄金律です。細かいことは他の人に任せてください。代わりに、実際のコーディングの問題、そして明らかにコーディングについて熟考することに時間を費やしてください。

于 2009-03-16T11:38:04.357 に答える
0

1-一般的なJavaセッターイディオム:

 public void setFoo(int foo) {
     this.foo = foo;
 }

2-このオブジェクトをパラメータとして関数を呼び出す場合

notifier.addListener(this);
于 2008-09-20T03:47:38.073 に答える
0

それは私が取り組んでいるコーディング標準に依存します。インスタンス変数を示すために_を使用している場合、「this」は冗長になります。_を使用していない場合、インスタンス変数を示すためにこれを使用する傾向があります。

于 2008-08-22T19:30:42.880 に答える
0

JohnMcGと同じようにIntellisenseを呼び出すために使用しますが、完了したら戻って「this->」を消去します。メンバー変数の前に "m_" を付ける Microsoft の規則に従っているため、ドキュメントとして残しておくと冗長になります。

于 2008-09-19T20:09:16.663 に答える
0

C++ でまだ言及されていない用途が 1 つあります。それは、独自のオブジェクトを参照したり、受け取った変数からメンバーを明確にしたりすることではありません。

を使用thisして、他のテンプレートから継承するテンプレート クラス内で、非依存名を引数依存名に変換できます。

template <typename T>
struct base {
   void f() {}
};

template <typename T>
struct derived : public base<T>
{
   void test() {
      //f(); // [1] error
      base<T>::f(); // quite verbose if there is more than one argument, but valid
      this->f(); // f is now an argument dependent symbol
   }
}

テンプレートは、2 パス メカニズムでコンパイルされます。最初のパスでは、引数に依存しない名前のみが解決およびチェックされますが、依存する名前は、テンプレート引数を実際に置換することなく、一貫性についてのみチェックされます。

そのステップでは、実際に型を置換することなく、コンパイラは何base<T>ができるかについての情報をほとんど持っていないため (ベース テンプレートの特殊化により、未定義の型であっても完全に異なる型に変わる可能性があることに注意してください)、型であると想定するだけです。 . fこの段階では、プログラマーにとって当然のことと思われる非依存呼び出しは、コンパイラーが名前空間のメンバーとして、derivedまたはそれを囲む名前空間内で見つけなければならないシンボルであり、これは例では発生しませんが、文句を言うでしょう。

解決策は、非依存名fを依存名に変えることです。これは、実装されているタイプを明示的に指定することにより、いくつかの方法で実行できます ( -- をbase<T>::f追加するbase<T>と、シンボルが依存するようにTなり、コンパイラはシンボルが存在すると想定し、2 番目のパスの実際のチェックを延期します。引数の置換。

2 つ目の方法は、複数の引数または長い名前を持つテンプレートから継承する場合はthis->、シンボルの前に a を追加するだけです。実装しているテンプレート クラスは引数に依存する (から継承するbase<T>)ため、引数にthis->依存し、同じ結果が得られthis->fます。テンプレート パラメーターの置換後、2 番目のラウンドでチェックされます。

于 2010-02-02T08:22:36.420 に答える
-2

どうしても必要な場合を除き、「this」は使用しないでください。

不必要な冗長性に関連するペナルティがあります。必要なだけの長さのコードを作成するように努める必要があります。

于 2008-09-02T16:42:19.263 に答える
-8

一度もない。これまで。変数のシャドウイングを使用している場合、命名規則は破られています。つまり、メンバー変数の名前を区別しないということですか? フェイスパーム

于 2008-08-22T19:53:31.173 に答える