IT story

"this"키워드는 언제 사용합니까?

hot-time 2020. 4. 6. 08:13
반응형

"this"키워드는 언제 사용합니까? [닫은]


다른 사람들 이이 키워드를 어떻게 사용하는지 궁금했습니다 . 생성자에서 사용하는 경향이 있지만 클래스 전체에서 다른 방법으로 사용할 수도 있습니다. 몇 가지 예 :

생성자에서 :

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

다른 곳

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

키워드는 C #에서 여러 가지 용도로 사용 됩니다.

  1. 유사한 이름으로 숨겨진 회원 자격을 부여하려면
  2. 객체가 다른 메소드에 매개 변수로 전달되도록하려면
  3. 객체가 메소드에서 자신을 리턴하게하려면
  4. 인덱서를 선언하려면
  5. 확장 메서드를 선언하려면
  6. 생성자간에 매개 변수를 전달하려면
  7. 값 유형 (struct) value을 내부적으로 다시 지정합니다 .
  8. 현재 인스턴스에서 확장 메서드를 호출하려면
  9. 다른 유형으로 자신을 캐스팅하려면
  10. 같은 클래스에 정의 된 생성자를 연결하려면

예를 들어 일반적인 명명 규칙을 따르고 필드 (낙타 케이스) 대신 속성 (파스칼 케이스)을 사용하여 로컬 변수와 충돌하지 않도록 범위 내에서 이름이 같은 멤버 및 로컬 변수가없는 경우 첫 사용을 피할 수 있습니다 (낙타) 케이스). C # 3.0에서는 자동 구현 된 속성 을 사용하여 필드를 속성으로 쉽게 변환 할 수 있습니다 .


나는 이것이 으르렁 거리는 소리를 의미하지는 않지만 중요하지 않습니다.

진심으로.

프로젝트, 코드, 직업, 개인 생활 등 중요한 것들을 살펴보십시오. "this"키워드를 사용하여 필드에 액세스 할 수 있는지 여부에 따라 성공을 거두지 않을 것입니다. 이 키워드는 정시에 배송하는 데 도움이되지 않습니다. 버그를 줄이지 않으며 코드 품질이나 유지 관리성에 별다른 영향을 미치지 않습니다. 그것은 당신에게 인상을 주거나 사무실에서 더 적은 시간을 보내지 않을 것입니다.

정말 스타일 문제 일뿐입니다. "this"가 마음에 들면 사용하십시오. 당신이하지 않으면하지 마십시오. 올바른 의미를 얻기 위해 필요한 경우 사용하십시오. 사실 모든 프로그래머는 자신 만의 고유 한 프로그래밍 스타일을 가지고 있습니다. 이 스타일은 "가장 미적으로 유쾌한 코드"의 모습에 대한 특정 프로그래머의 개념을 반영합니다. 정의에 따르면 코드를 읽는 다른 프로그래머는 다른 프로그래밍 스타일을 갖게됩니다. 즉, 다른 사람이 좋아하지 않거나 다르게 수행 한 일이 항상있을 것입니다. 어느 시점에서 어떤 사람은 코드를 읽고 무언가에 대해 불평합니다.

나는 그것을 걱정하지 않을 것입니다. 나는 당신의 취향에 따라 코드가 가능한 한 심미적으로 기쁘게하는지 확인합니다. 프로그래머 10 명에게 코드 형식을 지정하는 방법을 묻는다면 약 15 가지의 다른 의견이 나옵니다. 초점을 맞추는 것이 더 좋은 방법은 코드가 어떻게 반영되는지입니다. 상황이 올바르게 추상화 되었습니까? 의미있는 이름을 골랐나요? 코드 중복이 많이 있습니까? 물건을 단순화 할 수있는 방법이 있습니까? 그런 것들을 올바르게하는 것이 프로젝트, 코드, 직업 및 인생에 가장 긍정적 인 영향을 줄 것이라고 생각합니다. 우연히도, 아마도 다른 사람이 가장 덜 중얼 거릴 수도 있습니다. 코드가 작동하고, 읽기 쉽고, 잘 이해되면, 다른 사람은 필드를 초기화하는 방법을 면밀히 조사하지 않을 것입니다. 그는 단지 코드를 사용하고 위대함에 감탄하고


나는 절대적으로 필요한 경우, 즉 다른 변수가 다른 변수를 가리고있을 때만 사용합니다. 여기와 같이 :

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가 지적한 것처럼 이것을 매개 변수로 전달해야합니다. (로컬 변수는 멤버 변수보다 우선합니다)


개인적으로, 나는 멤버 변수를 언급 할 때 항상 이것을 사용하려고 합니다. 코드를 명확하게하고 더 읽기 쉽게 만듭니다. 모호성이 없어도 처음으로 내 코드를 읽는 사람은 그것을 알지 못하지만 이를 일관되게 사용하면 멤버 변수를보고 있는지 알 수 있습니다.


필요하지 않더라도 인스턴스 변수를 참조 할 때마다 사용합니다. 코드가 더 명확하다고 생각합니다.


나는 그것을 사용한다고 말하는 모든 사람들이 항상 "모범 사례"라고 믿을 수는 없다.

Corey의 예 와 같이 모호성이 있거나 Ryan의 예 와 같이 객체를 매개 변수로 전달해야하는 경우 "this"를 사용하십시오 . 스코프 체인을 기반으로 변수를 분석 할 수 있다는 것은 변수가 포함 된 한정 변수가 필요하지 않을 정도로 명확해야하기 때문에 달리 사용할 이유가 없습니다.

편집 : "this"에 대한 C # 설명서는 위에서 언급 한 "this"키워드에 대해 색인 작성기 선언에 대해 한 번 더 사용했음을 나타냅니다.

편집 : @ JUAN : 허, 내 진술에 불일치가 보이지 않습니다. "this"키워드를 사용하는 경우는 3 가지가 있습니다 (C # 설명서에 설명되어 있음) . 실제로 필요할 때입니다. 섀도 잉이 없을 때 생성자에서 변수 앞에 "this"를 고수하는 것은 단순히 키 스트로크를 낭비하고 그것을 읽을 때 내 시간을 낭비하는 것이므로 아무런 이점이 없습니다.


StyleCop이 지시 할 때마다 사용합니다 . StyleCop 을 준수해야합니다. 바로 이거 야.


언제든지 현재 객체에 대한 참조가 필요합니다.

특히 편리한 시나리오 중 하나는 객체가 함수를 호출하고 자신에게 함수를 전달하려는 경우입니다.

예:

void onChange()
{
    screen.draw(this);
}

우리가 다루고있는 인스턴스 멤버임을 분명히하기 위해 어디에서나 사용하는 경향이 있습니다.


나는 모호성이있을 수있는 곳이라면 어디에서나 사용합니다 (분명히). 컴파일러 모호성 (이 경우에는 필요)뿐만 아니라 코드를보고있는 누군가에게 모호성도 있습니다.


this 키워드의 또 다른 드문 용도는 구현 클래스 내에서 명시 적 인터페이스 구현을 호출해야하는 경우입니다. 다음은 좋은 예입니다.

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

    object ICloneable.Clone()
    {
        throw new NotImplementedException();
    }
}

내가 그것을 사용할 때입니다 :

  • 클래스 내에서 프라이빗 메소드에 액세스 (차별화)
  • 현재 객체를 다른 메소드로 전달 (또는 이벤트의 경우 발신자 객체로)
  • 확장 방법을 만들 때 : D

개인 필드 변수 이름 앞에 밑줄 (_)을 붙이기 때문에 개인 필드에는 이것을 사용하지 않습니다.


[C ++]

"여러분이 필요할 때 사용"여단에 동의합니다. 불필요하게 코드를 장식 이 것은 당신이 그것을 할 것을 잊지 때 컴파일러가 경고를하지 않기 때문에 좋은 생각이 아니다. 기대하는 사람들이 소개하고 잠재적 인 혼란 항상로는, 즉, 그들은해야합니다 생각 그것에 대해.

그래서 언제 사용하겠습니까? 난 그냥 (나는 이러한 여부에 판단을 통과 아니에요 어떤 임의의 코드 주위에보고했고,이 예제를 발견했습니다 좋은 수행하거나하는 일이) :

  • "자신"을 함수에 전달
  • 포인터 또는 이와 유사한 것에 "자신"을 할당합니다.
  • 캐스팅, 즉 업 / 다운 캐스팅 (안전 또는 기타), 불변성 캐스팅 등
  • 컴파일러는 명확성을 강조했습니다.

당신은 항상 그것을 사용해야합니다. 개인 필드와 매개 변수를 구분하는 데 사용합니다 (네이밍 규칙에 따라 멤버와 매개 변수 이름에 접두사를 사용하지 않기 때문에 인터넷에서 찾은 정보를 기반으로하므로 모범 사례))


동일한 유형의 객체에 대한 참조를 허용하는 함수에서 내가 참조하는 객체를 어디에서나 완벽하게 명확하게 하고 싶을 때 사용합니다 .

예를 들어

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() ;
  }
} ;

(vs)

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

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

AABB는 어떤 것을 한눈에 볼 right()수 있습니까? this약간의 청징 제를 추가합니다.


Jakub Šturc의 답변에서 컨스트럭터 사이에 데이터를 전달하는 것에 대한 그의 # 5는 아마도 약간의 설명을 사용할 수 있습니다. 이것은 오버로드 생성자에 있으며 사용 this이 필수 인 경우입니다. 다음 예제에서는 기본 매개 변수를 사용하여 매개 변수없는 생성자에서 매개 변수화 된 생성자를 호출 할 수 있습니다.

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

나는 이것이 때때로 유용한 기능이라는 것을 알았다.


Visual C ++에서 자유롭게 사용하는 습관이 들었습니다. '>'키를 눌렀을 때 IntelliSense가 트리거되고 게으르다. (그리고 오타하기 쉬운)

그러나 전역 함수가 아닌 멤버 함수를 호출하는 것이 편리하다는 것을 알았으므로 계속 사용했습니다.


나는 _로 필드를 강조하는 경향이 있으므로 실제로 이것을 사용할 필요는 없습니다. 또한 R #은 어쨌든 그것들을 리팩토링하는 경향이 있습니다 ...


나는 같은 유형 내부에서 유형 속성을 참조 할 때 이것을 거의 사용 합니다. 다른 사용자가 언급했듯이 로컬 필드에 밑줄을 긋기 때문에 이것을 필요로하지 않아도 됩니다.


단일 인수 다형성으로 인해 한쪽의 메소드에 넣어야하는 대칭 연산을 제외하고 필요한 경우에만 사용합니다.

boolean sameValue (SomeNum other) {
   return this.importantValue == other.importantValue;
} 

[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;
}

this C ++ 컴파일러에서

C ++ 컴파일러는 심볼을 즉시 찾지 못하면 자동으로 심볼을 찾습니다. 때때로, 대부분의 경우에 좋습니다 :

  • 자식 클래스에서 오버로드되지 않은 경우 어머니 클래스의 방법을 사용하십시오.
  • 한 유형의 가치를 다른 유형으로 승격

그러나 때로는 컴파일러가 추측하기를 원하지 않습니다. 컴파일러가 다른 심볼이 아닌 올바른 심볼을 선택하기를 원합니다.

나를 위해 , 그 시간은 메소드 내에서 멤버 메소드 또는 멤버 변수에 액세스하려고 할 때입니다. 나는 printf대신에 썼기 때문에 임의의 기호가 선택되는 것을 원하지 않습니다 print. this->printf컴파일하지 않았을 것입니다.

요점은 C 레거시 라이브러리 (§), 몇 년 전에 작성된 레거시 코드 (§§) 또는 복사 / 붙여 넣기가 더 이상 사용되지 않지만 여전히 활성 기능인 언어에서 발생할 수있는 모든 경우에 컴파일러가 재생하지 않도록 지시하는 것입니다 재치 좋은 아이디어입니다.

이것들이 내가 사용하는 이유 this입니다.

(§) 그것은 여전히 ​​나에게 일종의 미스터리이지만, 소스에 <windows.h> 헤더를 포함한다는 사실이 모든 기존 C 라이브러리 기호가 전역 네임 스페이스를 오염시키는 이유인지 궁금합니다.

(§§) "헤더를 포함해야하지만이 헤더를 포함하면 일반적인 이름을 가진 멍청한 매크로를 사용하기 때문에 코드가 손상된다"는 점이 코더의 삶의 러시아 룰렛 순간 중 하나라는 사실을 인식


'이.' 멤버가 많은 '이'클래스의 멤버를 찾는 데 도움이됩니다 (일반적으로 깊은 상속 체인으로 인해)

CTRL + Space를 치면 유형도 포함되므로 도움이되지 않습니다. 어디서나 'this' 회원 만 포함합니다.

나는 보통 내가 찾은 것을 가지고 나면 그것을 삭제합니다.

스타일면에서, 만약 당신이 고독한 사람이라면-당신은 결정합니다; 회사를 위해 일하는 경우 회사 정책을 고수하십시오 (소스 제어의 내용을보고 다른 사람들이하는 일을보십시오). 회원 자격을 얻기 위해 그것을 사용한다는 점에서 옳고 그른 것도 아닙니다. 유일한 잘못된 점은 불일치입니다. 즉, 스타일의 황금률입니다. 니트 따기 다른 사람을 남겨주세요. 대신 실제 코딩 문제 (그리고 분명히 코딩)를 숙고하는 데 시간을 보내십시오.


할 수있을 때마다 사용합니다. 코드가 더 읽기 쉽고 코드가 많을수록 버그가 적고 유지 관리 성이 향상됩니다.


동일한 코드 기반으로 작업하는 많은 개발자 인 경우 일부 코드 지침 / 규칙이 필요합니다. 내가 일하는 곳에서는 필드, 속성 및 이벤트에 'this'를 사용하기를 원했습니다.

나에게 이렇게하는 것이 좋습니다. 클래스 변수와 메소드 변수를 구별 할 때 코드를 쉽게 읽을 수 있습니다.


작업중 인 코딩 표준에 따라 다릅니다. _를 사용하여 인스턴스 변수를 표시하면 "this"가 중복됩니다. _를 사용하지 않으면 인스턴스 변수를 나타내는 데 사용하는 경향이 있습니다.


JohnMcG 와 마찬가지로 Intellisense 를 호출하는 데 사용 하지만, 끝나면 "this->"로 돌아가서 지 웁니다. 멤버 변수 앞에 "m_"접두어를 붙이는 Microsoft 규칙을 따르므로 문서로 남겨두면 중복됩니다.


1-공통 Java 세터 관용구 :

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

2-이 오브젝트를 매개 변수로 사용하여 함수를 호출 할 때

notifier.addListener(this);

C ++에서 아직 언급되지 않은 한 가지 용도가 있으며 자체 객체를 참조하거나 수신 된 변수에서 멤버를 명확하게하지 않습니다.

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

템플릿은 두 가지 패스 메커니즘으로 컴파일됩니다. 첫 번째 패스 중에는 인수가 아닌 종속 이름 만 확인되고 확인되며 종속 이름은 실제로 템플리트 인수를 대체하지 않고 일관성에 대해서만 점검됩니다.

이 단계에서 실제로 유형을 대체하지 않고 컴파일러는 무엇이 base<T>될 수 있는지에 대한 정보가 거의 없습니다 (기본 템플릿의 특수화는 정의되지 않은 유형조차도 완전히 다른 유형으로 바꿀 수 있음에 유의하십시오). . 이 단계에서 f프로그래머에게 자연스러워 보이는 비 의존적 호출 은 컴파일러가 derived네임 스페이스 의 멤버 또는 엔 클로징 네임 스페이스 (이 예제에서는 발생하지 않음)에서 찾아야 만하는 심볼입니다 .

해결책은 비 의존적 이름 f종속적 이름 으로 바꾸는 것입니다. 이 명시 적으로 구현하는 유형 (진술에 의해, 몇 가지 방법으로 수행 할 수 있습니다 base<T>::f(가) --adding base<T>의 기호에 의존하게 T컴파일러는 그냥 존재한다고 가정 할 것이다 연기합니다 후 두 번째 패스에 대한 실제 검사, 인수 대체.

두 번째 방법은 하나 이상의 인수 또는 긴 이름을 가진 템플릿에서 상속하는 경우 분류기 this->앞에 기호를 추가하는 것입니다. 구현하는 템플릿 클래스 가 인수에 의존 하므로 (에서 상 속됨 base<T>) this->인수에 종속적이며 동일한 결과를 얻습니다 this->f. 템플릿 매개 변수 대체 후 두 번째 라운드에서 확인됩니다.


꼭 필요한 경우가 아니면 "this"를 사용하지 마십시오.

불필요한 자세한 정보와 관련된 벌칙이 있습니다. 필요한 길이만큼 정확하게 코드를 만들려고 노력해야합니다.

참고 URL : https://stackoverflow.com/questions/23250/when-do-you-use-the-this-keyword

반응형