Сведения о вопросе

HEIGTH

21:06, 1st October, 2020

Теги

c#   .net   interface    

Члены Общественного интерфейсов C#

Просмотров: 502   Ответов: 9

В C#, при реализации интерфейса все члены являются неявно открытыми. Не было бы лучше , если бы мы могли указать модификатор доступности ( protected , internal, кроме private , конечно), Или мы должны просто использовать абстрактный класс вместо этого?



  Сведения об ответе

Chhiki

21:06, 1st October, 2020

Если интерфейс является внутренним, то все его члены будут внутренними для assembly. Если вложенный интерфейс защищен, только подклассы внешнего класса могут получить доступ к этому интерфейсу.

Внутренние члены для интерфейса вне его объявления assembly были бы бессмысленны, как и защищенные члены для интерфейса вне его объявления внешнего класса.

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

Для защищенных членов, вызываемых базовым классом, абстрактные классы - это способ задания контракта между базовыми классами и классами, которые наследуют от них. Но в этом случае детали реализации обычно очень важны, если только это не вырожденный чистый абстрактный класс (где все члены абстрактны), в котором защищенные члены бесполезны. В этом случае перейдите к интерфейсу и сохраните один базовый класс для реализации выбранных типов.


  Сведения об ответе

JUST___

14:32, 15th August, 2020

Вы можете скрыть реализацию интерфейса, явно указав имя интерфейса перед именем метода:

public interface IInterface {
    public void Method();
}

public class A : IInterface {
    public void IInterface.Method() {
        // Do something
    }
}

public class Program {
    public static void Main() {
        A o = new A();
        o.Method(); // Will not compile
        ((IInterface)o).Method(); // Will compile
    }
}


  Сведения об ответе

Chhiki

17:34, 16th August, 2020

Это не имело бы никакого смысла. Интерфейс-это контракт с общественностью , который вы поддерживаете этими методами и свойствами. Придерживайтесь абстрактных классов.


  Сведения об ответе

SILA

12:17, 20th August, 2020

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

Поскольку это самая обсуждаемая тема, позвольте мне опубликовать два отличных ответа, которые я нашел на SO, когда этот вопрос всплыл у меня в голове.

Этот ответ дает пример того, как может быть бессмысленно иметь неоднородные спецификаторы доступа для членов интерфейса в производных классах. Код всегда лучше технических описаний.

На мой взгляд, самое ужасное в принудительных открытых членах интерфейса - это то, что сам интерфейс может быть внутренним для assembly, но члены, которые он выставляет, должны быть открытыми. Джон Скит объясняет здесь, что это по дизайну печально .

Это поднимает вопрос, почему интерфейсы не были разработаны, чтобы иметь непубличные определения для членов. Это может сделать контракт гибким. Это довольно полезно при написании сборок, где вы не хотите, чтобы определенные члены классов были доступны за пределами assembly. Я не знаю почему.


  Сведения об ответе

#hash

03:54, 7th August, 2020

Интерфейс-это контракт, которого придерживаются все реализующие классы. Это означает, что они должны придерживаться всего этого или ничего из этого.

Если интерфейс является общедоступным, то каждая часть этого контакта должна быть общедоступной, иначе это будет означать одно для друзей / внутренних классов и другое для всего остального.

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


  Сведения об ответе

PAGE

09:52, 1st August, 2020

Вы можете скрыть почти весь код, реализованный интерфейсами к внешним сборкам.

interface IVehicle
{
    void Drive();
    void Steer();
    void UseHook();
}
abstract class Vehicle  // :IVehicle  // Try it and see!
{
    /// <summary>
    /// Consuming classes are not required to implement this method.
    /// </summary>
    protected virtual void Hook()
    {
        return;
    }
}
class Car : Vehicle, IVehicle
{
    protected override void Hook()  // you must use keyword "override"
    {
        Console.WriteLine(" Car.Hook(): Uses abstracted method.");
    }
    #region IVehicle Members

    public void Drive()
    {
        Console.WriteLine(" Car.Drive(): Uses a tires and a motor.");
    }

    public void Steer()
    {
        Console.WriteLine(" Car.Steer(): Uses a steering wheel.");
    }
    /// <summary>
    /// This code is duplicated in implementing classes.  Hmm.
    /// </summary>
    void IVehicle.UseHook()
    {
        this.Hook();
    }

    #endregion
}
class Airplane : Vehicle, IVehicle
{
    protected override void Hook()  // you must use keyword "override"
    {
        Console.WriteLine(" Airplane.Hook(): Uses abstracted method.");
    }
    #region IVehicle Members

    public void Drive()
    {
        Console.WriteLine(" Airplane.Drive(): Uses wings and a motor.");
    }

    public void Steer()
    {
        Console.WriteLine(" Airplane.Steer(): Uses a control stick.");
    }
    /// <summary>
    /// This code is duplicated in implementing classes.  Hmm.
    /// </summary>
    void IVehicle.UseHook()
    {
        this.Hook();
    }

    #endregion
}

Это позволит проверить код.

class Program
{
    static void Main(string[] args)
    {
        Car car = new Car();
        IVehicle contract = (IVehicle)car;
        UseContract(contract);  // This line is identical...
        Airplane airplane = new Airplane();
        contract = (IVehicle)airplane;
        UseContract(contract);  // ...to the line above!
    }

    private static void UseContract(IVehicle contract)
    {
        // Try typing these 3 lines yourself, watch IDE behavior.
        contract.Drive();
        contract.Steer();
        contract.UseHook();
        Console.WriteLine("Press any key to continue...");
        Console.ReadLine();
    }
}


  Сведения об ответе

KOMP

01:50, 22nd August, 2020

Интерфейсы не имеют модификаторов доступа в своих методах, оставляя их открытыми для любого подходящего модификатора доступа. Это имеет свою цель: он позволяет другим типам определить, какие методы и свойства доступны для объекта, следующего за интерфейсом. Предоставление им защищенных / внутренних средств доступа разрушает цель интерфейса.

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


  Сведения об ответе

VCe znayu

15:47, 22nd August, 2020

Я знаком с Java, а не с C#,, но с какой стати вам нужен частный член в интерфейсе? Он не мог иметь никакой реализации и был бы невидим для реализующих классов, поэтому был бы бесполезен. Существуют интерфейсы, определяющие поведение. Если вам нужно поведение по умолчанию, то используйте абстрактный класс.


  Сведения об ответе

DO__IT

06:15, 25th August, 2020

На мой взгляд, это нарушает инкапсуляцию. Я должен реализовать методы как общественных, то я реализую интерфейс. Я не вижу причин навязывать public в классе, который имплементирует интерфейс. (c#)


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться