C # переопределить открытый член и сделать его приватным - PullRequest
12 голосов
/ 24 августа 2011

возможно? Вы можете изменить доступ с что-нибудь на что-нибудь еще?

Ответы [ 3 ]

15 голосов
/ 24 августа 2011

Нет, вы можете скрыть открытый член с закрытым методом в подклассе, но вы не можете переопределить открытый член с закрытым методом в подклассе. И, на самом деле, это не просто публичная / приватная вещь, это относится к сужению доступа в целом.

Пересмотрено : скрывая более ограниченный доступ - в данном случае частный доступ - вы все еще увидите элемент базового класса из ссылки на базовый класс или подкласс, но это будет зависеть от нового метода, когда он доступен с нового уровня доступа.

Таким образом, в общем случае, когда вы скрываете, скрытие имеет приоритет, когда оно видно на уровне доступа. В противном случае используется оригинальный метод.

public class BaseClass
{
    public virtual void A() { }

    public virtual void B() { }
}

public class SubClass
{
    // COMPILER ERROR, can't override to be more restrictive access
    private override void A() { }

    // LEGAL, you can HIDE the base class method, but which is chosen 
    // depends on level accessed from
    private new void B() { }
}

Итак, SubClass.B() ТОЛЬКО скрывает методы базового класса, когда он доступен. То есть, если вы вызовете SubClass.B() внутри SubClass, тогда он примет скрытую форму B(), но, поскольку B() является закрытым, он не виден классам вне себя, и, таким образом, они ВСЕГДА увидят BaseClass.B().

Длинная и короткая: 1024 *

1) Вы не можете переопределить метод, чтобы быть более ограничительным (мудрый доступ). 2) Вы можете скрыть метод с более ограничительным, но он будет иметь эффект только там, где виден этот новый тип доступа, в противном случае базовый будет стоять.

public class BaseClass
{
    public virtual void A() { }
    public virtual void B() { }
}

public class SubClass : BaseClass
{
    public virtual void A() { B(); }

    // legal, you can do this and B() is now hidden internally in SubClass,
    // but to outside world BaseClass's B() is still the one used.
    private new void B() { }
}

// ...

SubClass sc = new SubClass();
BaseClass bc = new BaseClass();

// both of these call BaseClass.B() because we are outside of class and can't
// see the hide SubClass.B().
sc.B();
bc.B();

// this calls SubClass.A(), which WILL call SubClass.B() because the hide
// SubClass.B() is visible within SubClass, and thus the hide hides BaseClass.B()
// for any calls inside of SubClass.
sc.A();
3 голосов
/ 24 августа 2011

Нет.

Типичный способ справиться с этим - бросить NotImplementedException или что-то в этом роде.

2 голосов
/ 24 августа 2011

Вы не можете сузить или расширить видимость переопределенного члена. Однако вы можете определить другой метод с помощью ключевого слова new, который может дать вам новый метод с таким же именем , но несовместимый с точки зрения полиморфизма.

public class A : B
{
    public new void Foo()
    {
        base.Foo();
    }
}
...