[C#] 이 경우를 제외하고 C #으로 보호 된 멤버에 액세스 할 수없는 이유는 무엇입니까?


Answers

이것이 작동하지 않는 이유는 C #이 보호 된 메서드의 교차 계층 호출을 허용하지 않기 때문입니다. C 클래스에서 파생 된 클래스 E 있다고 가정 해보십시오.

  C
 / \
D   E

그런 다음 메소드를 호출하려고하는 참조가 실제로 유형 E 의 인스턴스가 될 수 있으므로 메소드가 런타임에 EF 해석 될 수 있습니다. E 는 계층 구조의 다른 분기에 있기 때문에 DE 의 보호 된 메서드를 호출 할 수 없으므로 C #에서는이 방법을 사용할 수 없습니다. 즉

var d = new D();
var e = new E();
d.G(e); // oops, now this will call E.F which isn't allowed from D

이는 protected 키워드가 멤버가 " 클래스 및 파생 클래스 인스턴스에서 액세스 할 수 있음 "을 의미하고 EF는 D의 멤버가 아니기 때문에 의미가 있습니다.

Question

이 코드 :

abstract class C
{
    protected abstract void F(D d);
}

class D : C
{
    protected override void F(D d) { }

    void G(C c)
    {
        c.F(this);
    }
}

이 오류를 생성합니다.

'C'유형의 규정자를 통해 보호 된 구성원 'CF (D)'에 액세스 할 수 없습니다. 규정자는 유형이 'D'(또는 그로부터 파생 됨) 여야하며,

그들은 무엇을 생각하고 있었습니까? (그 규칙을 바꾸면 뭔가 무언가가 깨질까요?) 그리고 F를 공개하는 것 외에 다른 방법이 있을까요?

편집 : 나는 왜 이것이 ( 그렉 고마워) 이유에 대한 이유를 얻지 만, 나는 여전히 합리적으로 조금 당황 스럽다. 주어진:

class E : C
{
    protected override void F(D d) { }
}  

왜 D가 EF에 전화 할 수 없습니까?

오류 메시지가 편집되어 거기에 오타가있을 수 있습니다.




예, 가능합니다. 우리는 아마 그러한 예가있을 것입니다.

그렇게하려면 다음을 수행해야합니다.

  1. 기본 폼 (EditAppointmentDialog)을 상속하고 사용자 지정을 수행합니다 (winforms 디자이너도 사용할 수 있습니다).

공용 부분 클래스 CustomAppointmentEditDialog : EditAppointmentDialog (private RadComboBox cmbShowTimeAs = null;

    public CustomAppointmentEditDialog() 
    { 
        InitializeComponent(); 

        this.cmbShowTimeAs = this.Controls["cmbShowTimeAs"] as RadComboBox; 
    } 

    private void chkConfirmed_ToggleStateChanged(object sender, StateChangedEventArgs args) 
    { 
        this.cmbShowTimeAs.SelectedValue = (args.ToggleState == ToggleState.On) ? 
            (int)AppointmentStatus.Busy : (int)AppointmentStatus.Tentative; 
    } 
} 

위의 코드에서 추가 체크 박스를 추가하고 미확인 상태 인 경우 미정으로 약속의 상태 (시간 표시)를 설정하고 선택하면 약속 있음으로 설정합니다. 콤보 상자에 액세스하는 이상한 방법은 현재 개인용이기 때문입니다. 이 내용은 2009 년 1 분기에 출시 될 예정으로 변경 될 예정입니다.

  1. RadScheduler의 AppointmentEditDialogShowing 이벤트를 구독하고 사용자 정의 된 양식으로 기본 양식을 대체하십시오.

private IEditAppointmentDialog appointmentEditDialog = null;

    protected override void OnLoad(EventArgs e) 
    { 
        base.OnLoad(e); 

        this.radScheduler1.AppointmentEditDialogShowing += new EventHandler<AppointmentEditDialogShowingEventArgs>(radScheduler1_AppointmentEditDialogShowing); 
    } 

    void radScheduler1_AppointmentEditDialogShowing(object sender, Telerik.WinControls.UI.AppointmentEditDialogShowingEventArgs e) 
    { 
        if (this.appointmentEditDialog == null) 
        { 
            this.appointmentEditDialog = new CustomAppointmentEditDialog(); 
        } 
        e.AppointmentEditDialog = this.appointmentEditDialog; 
    } 

이게 도움이 되길 바란다. 추가 질문이 있으면 주저하지 말고 다시 쓰십시오.




이 제한 사항은 정적 보호 방법을 사용하여 무시할 수 있습니다.

abstract class C
{
    protected abstract void F (D d);

    // Allows calling F cross-hierarchy for any class derived from C
    protected static void F (C c, D d)
    {
        c.F(d);
    }
}

class D : C
{
    protected override void F (D d) { }

    void G (C c)
    {
        // c.F(this);
        F(c, this);
    }
}

이것은 보안의 관점에서 완벽하지는 않습니다 (누구나 C 에서 파생 될 수 있음).하지만 C 클래스의 공용 인터페이스에서 F 메서드를 숨길 경우이 트릭이 유용 할 수 있습니다.