2009-03-04 1 views
2

자, 우정으로 인하여 캡슐화가 중단되는지 여부를 놓고 토론을 떠나 보자. 실제로 일관된 디자인으로 우아하게 시도해 보자. 나는이 기능이 필요한 이유는 무엇C#에서 친구 (C++에서 사용 가능) 구현하기

public class A 
    { 
     friend class B; 
    } 


2) : 구현하는 방법에 대한

1) 일반 질문 : 그것은 두 배 기능입니까? 일부 클래스는 ISerializable 인터페이스를 구현합니다. 그러나 ISerializable 메소드를 파생 클래스에서 보호하여 클라이언트 (문서뿐만 아니라)에 공개하지 않도록하고 싶습니다. 그러나 내부 클래스가 액세스 할 수 있어야합니다. C#에서이 문제를 해결하는 일반적인 방법은 무엇입니까?

참고 : 현재 C++ 표준에 정의 된대로 우정을 사용하고 있습니다. 동일한 어셈블리의 다른 유형의 형태는 내부 참조 표시되도록

감사

답변

1

, 당신은 단지 두 가지 선택이있다 :

  • 는 명시 적 인터페이스 구현을 사용하여 구현 public 메소드로 구현

두 경우 모두 누구나 메소드를 호출 할 수 있지만 명시 적 인터페이스 구현을 사용하면 인터페이스 표현식을 통해 메소드를 호출 할 수 있습니다 (예 : 실제 유형의 변수를로 캐스트 할 수 있음).).

"내부적으로"인터페이스를 구현하는 것과 같은 개념은 없습니다.

+0

이것은 내 생각이었습니다. 그러나 논쟁을 위해서 인터페이스 구현 방법을 내부로 표시하려고하면 어떻게됩니까? –

+0

더 이상 인터페이스를 구현하지 않으며 컴파일 타임 오류가 발생합니다. 내 질문에 대한 답변이 실제로 주어 졌을 때 내 대답이 downvoted 된 이유는 확실하지 않습니다. –

+0

Jon, 질문의 첫 번째 부분을 해결했습니다. 실제로는 클라이언트가 메서드를 호출하지 못하게됩니다. 두 번째 부분 :이 메소드를 공개하지 않기를 바란다. 그렇지 않으면 doxygen이 문서를 문서로 내 보내어 API 사용자를 혼란스럽게 만든다. 내가 너에게 표를 줬어. –

4

C 번호는 internal 키워드를 갖는다. 또한 attributes을 어셈블리에 추가하여 어셈블리 외부의 형식이 해당 어셈블리의 내부 멤버를 볼 수 있도록 할 수 있습니다.

+0

예를 들어주십시오. 디자인의 목표는 CLIENT가이 방법의 존재에 대해 아무것도 모르는 것을 확인하는 것입니다. –

+0

클라이언트는 항상 리플렉션을 사용하여 모든 방법을 발견 할 수 있습니다. –

0

internal 현재 회원은 현재의 .dll 및 공용 회원 외부에서 공개됩니다. 또한 InternalsVisibleTo 특성을 사용하여 외부 .dll 파일에 노출 할 수 있습니다.

4

클래스가 동일한 어셈블리에 있으면 internal을 사용할 수 있습니다. 다른 어셈블리에있는 경우 friend assembly attribute을 사용할 수 있습니다. 그것을 구현하는 인터페이스에 올 때 InternalsVisibleTo 물건 하나 측면을 떠나

+0

좋습니다! 감사합니다 ... –

0

저는 개인용 싱글 톤 인스턴스를 "키"로 사용하여 호출자가 자신이 말하는 사람임을 증명하는 여러 가지 솔루션을 제공합니다.

해결 방법 1 : 친구 클래스는 싱글에게 있습니다

public class A 
{ 
    private underwear myUnderwear; 

    public ChangeUnderwear(B friend, underwear newUnderwear) 
    { 
    if (friend == null) return; 
    myUnderwear = newUnderwear 
    } 
} 

public sealed class B 
{ 
    private B() {}; 
    private B inst; 
    private MessWithA(A a) 
    { 
    a.ChangeUnderwear(this, new Thong()); 
    } 
} 

사람이 모든 결함을 볼 수 있습니까? 이 기술은 Foo 클래스와 FooManager 싱글 톤이있는 경우 작동합니다.

해결 방법 2 : 친구가 싱글이 아닌 경우, 당신이 건설을 숨기고 모든 인스턴스 숨기는 같은 생각 사용할 수 있습니다 같아요

interface IB 
{ ... } 

public sealed class B : IB 
{ 
    private B() {}; 
    public IB CreateB() 
    { 
    return (IB)new B(); 
    } 
    private MessWithA(A a) 
    { 
    a.ChangeUnderwear(this, new Thong()); 
    } 
} 

을하지만 지금 당신은 지금 당신이를 방지 할 수있는 방법이 필요합니다 적을 단순히 IB를 B로 캐스팅 한 다음 B를 사칭하여 A의 친구 만 액세스 할 수 있습니다. 어떤 아이디어?

해결책 3 : 싱글 톤 클래스는 인스턴스를 요청한 첫 번째 호출자가 인스턴스를 소유하게합니다. 친구 클래스는 시작시 인스턴스를 잡으려고 시도하고 누군가 다른 사람이 먼저 잡는다면 화를냅니다.