внутренний участник в интерфейсе

Ошибка анализа: синтаксическая ошибка, неожиданный T_PAAMAYIM_NEKUDOTAYIM

Оператор разрешения области также называется «Paamayim Nekudotayim» с иврита פעמיים נקודתיים. это означает «двойная двоеточие» или «двойная точка дважды».

Эта ошибка обычно возникает, если вы случайно поместите :: в свой код.

Вопросы, относящиеся:

Документация:

33
задан nawfal 11 May 2013 в 10:52
поделиться

9 ответов

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

Теперь, рассмотрите то, что произошло бы, если бы был интерфейс как, Вы просите - общественность, но с одним внутренним участником. Что это означало бы? Внешний объект мог реализовать только открытые методы, но не внутренний. Когда Вы получили бы такой внешний объект, Вы будете в состоянии назвать только открытые методы, но не внутренний, потому что объект не мог реализовать его. Другими словами - контракт не был бы выполнен. Не все методы были бы реализованы.

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

39
ответ дан Vilx- 27 November 2019 в 17:46
поделиться

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

internal interface InternalIAM
{
    void Save();
}

public class concreteIAM : InternalIAM
{
    void InternalIAM.Save()
    {
    }
}
25
ответ дан angry person 27 November 2019 в 17:46
поделиться

Я не думаю, что необходимо использовать интерфейс здесь, возможно, необходимо использовать абстрактную основу что-то как.:

public abstract class AM
{
    public int ID { get; set; }
    internal abstract void Save();
}

public class concreteIAM : AM
{
    internal override void Save()
    {
        //Do some save stuff
    }
}

все еще позволит Вам делать это:

public class AMList : List<AM>
{
    public void SaveItems()
    {
        foreach (var item in this)
        {
            item.Save();
        }
    }
}
9
ответ дан Nathan W 27 November 2019 в 17:46
поделиться

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

using System;

public interface IPublic
{
    void Public();
}

internal interface IInternal : IPublic
{
    void Internal();
}

public class Concrete : IInternal
{
    public void Internal() { }

    public void Public() { }
}
7
ответ дан Andrew Hare 27 November 2019 в 17:46
поделиться

Если Вы не хотите, чтобы внешние вызывающие абоненты были в состоянии назвать Ваше Сохранение () методом, почему бы не сделать целый concreteIAM класс внутренним?

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

1
ответ дан Brannon 27 November 2019 в 17:46
поделиться

Возможно, Вы хотите разделить сохранение своих объектов в различный набор классов, которые являются внутренними к Вашему блоку:

internal interface IAMSaver { void Save(IAM item); }

internal class AMSaverFactory {
  IAMSaver GetSaver(Type itemType) { ... }
}

public class MyList : List<IAM>
{
  public void Save()
  {
    foreach (IAM itemin this)
    {
      IAMSaver saver = SaverFactory.GetSaver(item.GetType());
      saver.Save(item)
    }
  }
}
1
ответ дан Andrew Kennan 27 November 2019 в 17:46
поделиться

Интерфейсные участники, как предполагается, общедоступны.. что-либо еще и Вы должны думать, нужно ли Вам что-то еще. В этом случае Вы

  • хотите, Сохраняют, чтобы быть интерфейсным участником
  • , хотят, Сохраняют, чтобы быть только позволенным через другой класс под названием MyList, который находится в том же блоке
  • , запрещают, Сохраняют от того, чтобы быть названным внешне (от других классов вне родительского блока)

мысли дизайна Хранения в стороне, Вы могли сделать это через Явную Интерфейсную Реализацию.

    internal interface IPersist
    {
        void Save();
    }
    public class Concrete : IPersist
    {
        void IPersist.Save()
        {
            Console.WriteLine("Yeah!");
        }
    }

// Mylist.cs in the same assembly can still call save like
public void SaveItems()
    {
        foreach (IPersist item in this)
        {
            item.Save();
        }
    }

IPersist является внутренним, не доступным вне родительского блока и так как это явно реализовано, это нельзя назвать без ссылки IPersist.

new Concrete().Save();     // doesn't compile. 'Concrete' does not contain a definition for 'Save'

Обновление От Вашего последнего ответа, у нас есть больше ограничений. Интерфейс должен быть общедоступным, он должен содержать метод Сохранения, который не должен быть общедоступным. Я сказал бы, идут назад к исходной точке..., что-то не кажется правильным. По моему скромному мнению, Вы не можете сделать этого с единственным интерфейсом. Как насчет того, чтобы разделить на 2 интерфейса, общедоступный и внутренний?

1
ответ дан Gishu 27 November 2019 в 17:46
поделиться

Почему Вы не используете внутренние классы для управления доступностью методов?

Пример:

Ваш основной блок

public abstract class Item
{
    public int ID { get; set; }
    protected abstract void Save();

    public class ItemCollection : List<Item>
    {
        public void Save()
        {
            foreach (Item item in this) item.Save();
        }
    }
}

Ваш вторичный блок

public sealed class NiceItem : Item
{
    protected override void Save()
    {
        // do something
    }
}

Этот шаблон все еще позволит Вам реализовать Save() метод в других блоках, но [только 113], который является внутренним классом Item, могут назвать его. Блестящий, не так ли?

1
ответ дан lubos hasko 27 November 2019 в 17:46
поделиться

Пойдите с двумя интерфейсами:

public interface IAM
{
        int ID { get; set; }
}


internal interface IAMSavable
{
        void Save();
}

public class concreteIAM : IAM, IAMSavable
{
         public int ID{get;set;}
         public void IAMSavable.Save(){
         //save the object
         }

        //other staff for this particular class
}

public class MyList : List<IAM>
{
        public void Save()
        {
                foreach (IAM iam in this)
                {
                        ((IAMSavable)iam).Save();
                }
        }

        //other staff for this particular class
}

реализация Сохранения () должна быть явной для предотвращения клиентов, называющих его.

0
ответ дан MZywitza 27 November 2019 в 17:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: