Оператор разрешения области также называется «Paamayim Nekudotayim» с иврита פעמיים נקודתיים. это означает «двойная двоеточие» или «двойная точка дважды».
Эта ошибка обычно возникает, если вы случайно поместите ::
в свой код.
Вопросы, относящиеся:
Документация:
Я думаю, что Вы не понимаете то, для чего интерфейс. Интерфейс контракт . Это определяет, что объект ведет себя определенным способом. Если объект реализует интерфейс, это означает, что можно полагаться на него, что это имеет реализованные методы всего интерфейса.
Теперь, рассмотрите то, что произошло бы, если бы был интерфейс как, Вы просите - общественность, но с одним внутренним участником. Что это означало бы? Внешний объект мог реализовать только открытые методы, но не внутренний. Когда Вы получили бы такой внешний объект, Вы будете в состоянии назвать только открытые методы, но не внутренний, потому что объект не мог реализовать его. Другими словами - контракт не был бы выполнен. Не все методы были бы реализованы.
я думаю, что решение в этом случае состоит в том, чтобы разделить Ваш интерфейс в два. Один интерфейс был бы общедоступен, и это - то, что реализовали бы Ваши внешние объекты. Другой интерфейс был бы внутренним и будет содержать Ваш Save()
и другие внутренние методы. Возможно, этот второй интерфейс мог даже наследоваться сначала. Ваши собственные внутренние объекты тогда реализовали бы оба интерфейса. Таким образом, Вы могли даже различать внешние объекты (которые не имеют внутреннего интерфейса), и внутренние объекты.
Сделайте другой интерфейс, который является внутренним, и используйте явную реализацию для метода.
internal interface InternalIAM
{
void Save();
}
public class concreteIAM : InternalIAM
{
void InternalIAM.Save()
{
}
}
Я не думаю, что необходимо использовать интерфейс здесь, возможно, необходимо использовать абстрактную основу что-то как.:
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();
}
}
}
Я думаю, что лучшая вещь сделать состояла бы в том, чтобы повредить внутренних и общедоступных участников в два отдельных интерфейса. При наследовании интерфейсов, можно все еще объявить участников публично, но видимость внутренних участников продиктует видимость самого интерфейса.
using System;
public interface IPublic
{
void Public();
}
internal interface IInternal : IPublic
{
void Internal();
}
public class Concrete : IInternal
{
public void Internal() { }
public void Public() { }
}
Если Вы не хотите, чтобы внешние вызывающие абоненты были в состоянии назвать Ваше Сохранение () методом, почему бы не сделать целый concreteIAM класс внутренним?
Или, если Вы хотите общественность класса, но не интерфейс, делают целый интерфейс внутренним. Я думаю, что внутренний интерфейс может быть добавлен к общедоступному классу (но я не попробовал его...)
Возможно, Вы хотите разделить сохранение своих объектов в различный набор классов, которые являются внутренними к Вашему блоку:
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)
}
}
}
Интерфейсные участники, как предполагается, общедоступны.. что-либо еще и Вы должны думать, нужно ли Вам что-то еще. В этом случае Вы
мысли дизайна Хранения в стороне, Вы могли сделать это через Явную Интерфейсную Реализацию.
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 интерфейса, общедоступный и внутренний?
Почему Вы не используете внутренние классы для управления доступностью методов?
Пример:
Ваш основной блок
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
, могут назвать его. Блестящий, не так ли?
Пойдите с двумя интерфейсами:
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
}
реализация Сохранения () должна быть явной для предотвращения клиентов, называющих его.