숨길 의도가 있다면 새 키워드를 사용
숨길 의도가 있다면 새 키워드를 사용
VS2008에서 "숨기기가 의도 된 경우 새 키워드 사용"경고를 생성하는 다음 코드 조각이 있습니다.
public double Foo(double param)
{
return base.Foo(param);
}
Foo()
기본 클래스 의 함수는 보호되며 단위 테스트 목적으로 만 래퍼 클래스에 넣어 단위 테스트에 노출하고 싶습니다. 즉, 래퍼 클래스는 다른 용도로 사용되지 않습니다. 그래서 한 가지 질문이 있습니다. 이것이 허용되는 관행입니까?
new
경고로 돌아갑니다 . 이 시나리오에서 재정의 기능을 새로 만들어야하는 이유는 무엇입니까?
은 new
당신이 기존의 방법을 통해 쾅쾅 알고 것을 절대적으로 명확합니다. 기존 코드가 였기 때문에 protected
큰 문제는 아닙니다.를 추가하여 new
신음 하는 것을 막을 수 있습니다.
당신의 방법이 다른 일을 할 때 차이가 있습니다. 파생 클래스 를 참조 하고 호출 하는 모든 변수 Foo()
는 기본 클래스 를 참조 하고 다음을 호출 하는 것과는 다른 작업을 수행합니다 (동일한 객체를 사용하더라도) Foo()
.
SomeDerived obj = new SomeDerived();
obj.Foo(); // runs the new code
SomeBase objBase = obj; // still the same object
objBase.Foo(); // runs the old code
이것은 분명히 알고 SomeDerived
호출 하는 기존 코드에 영향을 미칠 수 있습니다. Foo()
즉, 이제 완전히 다른 메서드를 실행하고 있습니다.
또한 표시 할 수 protected internal
있으며 [InternalsVisibleTo]
단위 테스트에 대한 액세스를 제공 하는 데 사용할 수 있습니다 (이는 가장 일반적인 사용입니다 [InternalsVisibleTo]
. 그러면 단위 테스트가 파생 클래스없이 직접 액세스 할 수 있습니다.
핵심은 메서드를 재정의 하지 않는다는 것입니다. 당신은 그것을 숨기고 있습니다. 재정의하는 경우 override
키워드 가 필요합니다 (가상이 아닌 경우 컴파일러는 비가 상 메서드를 재정의 할 수 없기 때문에 불평 할 것입니다 ).
이 new
키워드를 사용하여 컴파일러와 코드를 읽는 모든 사람에게 "괜찮습니다. 기본 메서드를 숨기고 재정의하지 않는 것입니다. 그게 제가 의도 한 바입니다."
솔직히 저는 메서드를 숨기는 것이 좋지 않다고 생각합니다. Craig가 제안한 것처럼 다른 메서드 이름을 사용하겠습니다.하지만 그것은 다른 논의입니다.
이름없이 가시성을 변경하고 있습니다. 함수 TestFoo를 호출하면 작동합니다. 예, IMHO는 이런 이유로 하위 클래스를 허용합니다.
new
키워드를 숨기는 데 사용할 수 있지만 대부분의 경우 피할 수있는 까다로운 상황이 항상 있습니다.
그러나 최근에 저는이 키워드가 정말 필요했습니다. 그 이유는 주로 언어에 기존 접근자를 완성하기위한 다른 적절한 synthax 기능이 없기 때문입니다.
다음과 같은 구식 수업을 고려한다면 :
KeyedCollection<TKey, TItem>
인덱스를 통해 항목에 액세스하는 액세서는 다음과 같습니다.
TItem this[Int32 index] { get; set; }
둘 다 가지고 { get; set; }
그들은 관한 인해 상속에 물론 필수로되어 ICollection<T>
및 Collection<T>
하지만, 단 하나의 존재 { get; }
(I는이 디자인에 대한 몇 가지 추측이 그 이유의 많음이 내가 고른 것을 참고하시기 바랍니다,이 열쇠를 통해 항목을 acessing를 들어 위쪽 KeyedCollection<TKey, TItem>)
) 그림의 목적을 위해 단지.
어쨌든 키 액세스에 대한 게터는 하나뿐입니다.
TItem this[TKey key] { get; }
하지만 내가 { set; }
지원 을 추가하고 싶다면 , 기술적으로 말하면, 특히 속성의 이전 정의에서 추론을 계속한다면 그것은 그저 방법 일뿐입니다. 유일한 방법은 명시 적으로 다른 더미 인터페이스를 구현하는 것입니다. 암시 적으로 만들고 싶다면 new
키워드 를 만들어야 합니다. 저는 접근 자 정의를 숨기고 있습니다. 기본 정의를 설정하고 몇 가지 개인적인 것으로 채워진 세트를 추가하면 작동합니다.
저는이 매우 구체적인 시나리오에 대해이 키워드가 완전히 적용 가능하다고 생각합니다. 특히 { get; }
부분에 대해 가져 오지 않은 상황과 관련하여 그렇습니다 .
public new TItem this[TKey key]
{
get { return base... }
set { ... }
}
이것이 컴파일러가 당신이 무엇을하고 있는지 깨닫지 못한 채 숨고 있을지도 모른다고 제안하는 이런 종류의 경고를 피하는 유일한 방법입니다.
참조 URL : https://stackoverflow.com/questions/451035/use-new-keyword-if-hiding-was-intended