내부 클래스에서 공개 메소드를 사용하는 이유는 무엇입니까?
프로젝트 중 하나에 다음과 같은 코드가 많이 있습니다.
internal static class Extensions
{
public static string AddFoo(this string s)
{
if (!string.IsNullOrEmpty(s)) return s + "Foo";
return "Foo";
}
}
"나중에 유형을 공개하는 것이 더 쉬운 것"이외의 다른 명백한 이유가 있습니까?
나는 그것이 매우 이상한 가장자리 케이스 (Silverlight에서의 반사)에서만 중요하거나 전혀 그렇지 않다고 생각합니다.
업데이트 :이 질문은 2014 년 9 월 내 블로그의 주제였습니다 . 좋은 질문 감사합니다!
컴파일러 팀 자체 내에서도이 질문에 대해 상당한 논쟁이 있습니다.
우선, 규칙을 이해하는 것이 현명합니다. 클래스 또는 구조체의 공용 멤버 는 포함 형식에 액세스 할 수있는 모든 항목에 액세스 할 수있는 멤버입니다 . 따라서 내부 클래스의 공개 멤버는 사실상 내부입니다.
이제 내부 클래스가 주어지면 어셈블리에서 액세스하려는 멤버를 공개 또는 내부로 표시해야합니까?
내 의견은 : 그런 회원들을 공개로 표시하십시오.
"public"을 사용하여 "이 멤버는 구현 세부 정보가 아닙니다"를 의미합니다. 보호 된 멤버는 구현 세부 사항입니다. 파생 된 클래스 작업을 수행하는 데 필요한 내용이 있습니다. 내부 멤버는 구현 세부 사항입니다. 이 어셈블리 내부의 다른 무언가가 올바르게 작동하려면 멤버가 필요합니다. 공용 구성원은 "이 구성원은이 개체에서 제공하는 주요 문서화 된 기능을 나타냅니다."라고 말합니다.
기본적으로 내 태도는 :이 내부 수업을 공개 수업으로 만들기로 결정했다고 가정 해 봅시다. 이를 위해 클래스의 접근성이라는 것을 정확히 변경하고 싶습니다 . 내부 클래스를 공개 클래스로 바꾸는 것이 내부 멤버도 공개 멤버로 바꿔야 한다는 것을 의미하는 경우 해당 멤버는 클래스 의 공개 영역 의 일부였으며 처음에는 공개되어야했습니다.
다른 사람들은 동의하지 않습니다. 멤버 선언을 한눈에보고 내부 코드에서만 호출되는지 여부를 즉시 알고 싶다는 조건이 있습니다.
불행히도, 그것이 항상 잘 작동하는 것은 아닙니다. 예를 들어, 내부 인터페이스를 구현하는 내부 클래스는 클래스의 공용 영역의 일부 이므로 구현 멤버를 public으로 표시해야합니다 .
클래스 인 경우 internal
이 방법을 표시 여부, 그것은 접근성 관점에서 중요하지 않습니다 internal
또는 public
. 그러나 클래스가 있다면 사용할 유형을 사용하는 것이 여전히 좋습니다 public
.
일부는이에서 전환을 용이하게했다있는 반면 internal
에 public
. 또한 방법 설명의 일부로 사용됩니다. Internal
방법은 일반적으로 자유로운 액세스에 대해 안전하지 않은 public
것으로 간주되는 반면 방법은 (대부분) 무료 게임으로 간주됩니다.
수업 에서 internal
또는 수업 을 사용하는 public
것처럼 앞으로 어떤 public
수업에 액세스해야하는지 알려주는 동시에 수업 public
을 진행하는 데 필요한 작업을 완화 할 수 있습니다.
나는 종종 내부 클래스 대신 내부 클래스에서 메소드를 a) 실제로 중요하지 않으며 b) 내부 메소드를 사용하여 메소드가 의도적으로 내부임을 나타냅니다 (이 이유를 노출시키지 않으려는 이유가 있습니다) 따라서 내부 클래스가있는 경우 내부 메서드를 공개로 변경하기 전에 내부 이유를 이해해야하지만 내부 클래스에서 공개 메서드를 처리하는 경우 왜 내부 클래스에서 클래스는 각 메소드가 내부적 인 이유와 반대로 내부입니다.
"나중에 유형을 공개하는 것이 더 쉬운가요?" 그렇습니다.
범위 지정 규칙은 internal
메소드가 표시되는 방식으로 만 표시되므로 메소드가 표시되어 있는지 public
또는 중요하지는 않습니다 internal
.
명심해야 할 한 가지 가능성은 클래스 가 공개되었고 나중에 변경되었으며 internal
개발자가 모든 메소드 액세스 가능성 수정자를 변경하지 않았다는 것입니다.
경우에 따라 내부 유형에 공용 인터페이스가 구현되어 해당 인터페이스에 정의 된 모든 메소드를 여전히 공용으로 선언해야 할 수도 있습니다.
똑같습니다. 공개 메소드는 내부 클래스 내부에 있기 때문에 실제로 내부로 표시되지만 클래스를 공개로 표시하려면 코드를 더 적게 변경해야합니다.
internal
멤버는 동일한 어셈블리 내에서만 액세스 할 수 있습니다. 해당 어셈블리의 다른 클래스는 액세스 할 수있는 internal public
멤버 만 접근 a를 할 수 없을 것 private
또는 protected
회원 internal
여부.
나는 실제로 오늘 이것으로 고투했다. 지금까지 나는 internal
클래스가 internal
특히 엔터프라이즈 개발에서 단순히 나쁜 코딩이나 게으름으로 여겨 지면 메소드에 모두 표시해야한다고 말했다 . 그러나 클래스를 서브 클래스 화하고 public
메소드 중 하나를 재정의해야했습니다.
internal class SslStreamEx : System.Net.Security.SslStream
{
public override void Close()
{
try
{
// Send close_notify manually
}
finally
{
base.Close();
}
}
}
에릭 리퍼 트가 말한 것처럼 이 방법은 반드시 있어야하며 public
실제로 설정 internal
하지 않는 한 방법을 설정하는 논리적 근거가 없다고 생각 했다.
지금까지 나는 그것에 대해 생각하는 것을 결코 멈추지 않았고 방금 그것을 받아 들였지만 Eric의 게시물을 읽은 후에 정말 생각하고 많은 고의를 기울인 후에 많은 의미가 있습니다.
차이가 있습니다. 프로젝트에서 많은 클래스를 내부적으로 만들었지 만 다른 어셈블리에서 단위 테스트를 수행하고 어셈블리 정보에서 InternalsVisibleTo를 사용하여 UnitTest 어셈블리가 내부 클래스를 호출 할 수 있도록했습니다. 내부 클래스에 내부 생성자가 있으면 어떤 이유로 단위 테스트 어셈블리에서 Activator.CreateInstance를 사용하여 인스턴스를 만들 수 없습니다. 그러나 생성자를 public으로 변경했지만 클래스가 여전히 내부라면 잘 작동합니다. 그러나 나는 이것이 매우 드문 경우라고 생각합니다 (에릭처럼 원래 게시물에서 반사 :).
나는 이것에 대한 추가 의견이 있다고 생각합니다. 처음에는 내부 클래스에서 무언가를 대중에게 선언하는 것이 어떻게 의미가 있는지 궁금했습니다. 그런 다음 나중에 수업을 공개로 변경하기로 결정하면 좋을 것이라고 읽었습니다. 진실. 따라서 내 마음에 패턴이 형성되었습니다 . 현재 동작을 변경하지 않으면 허용하고 현재 코드 상태에서 의미가 없으며 아프지 않은 것을 허용하지만 나중에는 클래스 선언을 변경하십시오.
이처럼 :
public sealed class MyCurrentlySealedClass
{
protected void MyCurretlyPrivateMethod()
{
}
}
위에서 언급 한 "패턴"에 따르면 이것은 완벽하게 괜찮습니다. 그것은 같은 생각을 따릅니다. private
클래스를 상속받을 수 없으므로 메소드 로 작동 합니다. 그러나 sealed
제약 조건 을 삭제하면 여전히 유효합니다. 상속 된 클래스는이 방법을 볼 수 있습니다.이 방법은 내가 달성하고자하는 것입니다. 그러나 경고가 나타납니다 : CS0628
또는 CA1047
. 둘 다 클래스 protected
에서 멤버를 선언하지 않습니다 sealed
. 또한, 나는 그것이 무의미하다 그것에 대해, 전체 계약을 발견 : 경고 '봉인 클래스의 보호 된 멤버'(싱글 톤 클래스)
그래서이 경고와 토론이 연계 된 후에, 나는 내부 클래스에서 모든 것을 내부 또는 이하로 만들기로 결정했습니다. 왜냐하면 그것은 더 많은 종류의 사고에 부합하기 때문입니다. 우리는 다른 "패턴"을 섞지 않습니다.
참고 URL : https://stackoverflow.com/questions/9302236/why-use-a-public-method-in-an-internal-class
'IT story' 카테고리의 다른 글
UTC 타임 스탬프 받기 (0) | 2020.04.17 |
---|---|
IIS 응용 프로그램 풀이 란 무엇입니까? (0) | 2020.04.17 |
재귀 함수의 복잡성 결정 (Big O 표기법) (0) | 2020.04.17 |
객체의 모든 방법을 표시하는 방법? (0) | 2020.04.17 |
Visual Studio 2013에서 모든 CAPS 메뉴 항목을 사용하지 않도록 설정 (0) | 2020.04.17 |