Как ограничить доступ к вложенному участнику класса к включению класса?

Мне 21 год, и я использую энергию на данный момент 3 или 4 года... Я когда-то попробовал emacs, когда один из моего учителя сказал мне, что это было лучше, чем Vim..., но я предпочел свой рабочий процесс с энергией...

я пытался использовать emacs на прошлой неделе, потому что у меня была проблема при расположении с отступом файлов HTML... Но мой товарищ по команде потерял меня, когда он начал говорить о сочетании клавиш или чем-то как этот. Мое предположение - то, что энергия или emacs являются двумя великими редакторами... Это лучше, чем большая часть IDE, который я знаю.

Ползунки до всех.

57
задан Thomas Levesque 3 November 2009 в 03:27
поделиться

4 ответа

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

public class Journal
{
    public class JournalEntry
    {
        protected JournalEntry(object value)
        {
            this.Timestamp = DateTime.Now;
            this.Value = value;
        }

        public DateTime Timestamp { get; private set; }
        public object Value { get; private set; }
    }

    private class JournalEntryInstance: JournalEntry
    { 
        public JournalEntryInstance(object value): base(value)
        { }
    }
    JournalEntry CreateEntry(object value)
    {
        return new JournalEntryInstance(value);
    }
}

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

Если это тоже невозможно, вы всегда можете сделать конструктор закрытым и использовать отражение, чтобы вызвать это из вашего дневного класса:

typeof(object).GetConstructor(new Type[] { }).Invoke(new Object[] { value });

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

public class Journal
{
    private static Func<object, JournalEntry> EntryFactory;
    public class JournalEntry
    {
        internal static void Initialize()
        {
            Journal.EntryFactory = CreateEntry;
        }
        private static JournalEntry CreateEntry(object value)
        {
            return new JournalEntry(value);
        }
        private JournalEntry(object value)
        {
            this.Timestamp = DateTime.Now;
            this.Value = value;
        }

        public DateTime Timestamp { get; private set; }
        public object Value { get; private set; }
    }

    static Journal()
    {
        JournalEntry.Initialize();
    }

    static JournalEntry CreateEntry(object value)
    {
        return EntryFactory(value);
    }
}

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

46
ответ дан 24 November 2019 в 19:20
поделиться

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

Это решение фактически быстрее, чем решение на основе интерфейса для в большинстве случаев и проще кодировать.

public class Journal
{
  private static Func<object, JournalEntry> _newJournalEntry;

  public class JournalEntry
  {
    static JournalEntry()
    {
      _newJournalEntry = value => new JournalEntry(value);
    }
    private JournalEntry(object value)
    {
      ...
80
ответ дан 24 November 2019 в 19:20
поделиться

В этом случае вы можете либо:

  1. Сделать конструктор внутренним - это остановит создание новых экземпляров теми, кто находится вне этой сборки, либо ...
  2. Выполните рефакторинг класса JournalEntry для использования открытого интерфейса и сделайте фактический класс JournalEntry частным или внутренним. Затем интерфейс может быть открыт для коллекций, в то время как фактическая реализация скрыта.

Я упомянул internal как допустимый модификатор выше, однако, в зависимости от ваших требований, private может быть более подходящей альтернативой.

Изменить: Извините, я упомянул частный конструктор, но вы уже рассмотрели этот момент в своем вопросе. Приношу свои извинения за неправильное чтение!

private может быть более подходящей альтернативой.

Изменить: Извините, я упомянул частный конструктор, но вы уже рассмотрели этот момент в своем вопросе. Приношу свои извинения за неправильное чтение!

private может быть более подходящей альтернативой.

Изменить: Извините, я упомянул частный конструктор, но вы уже рассмотрели этот момент в своем вопросе. Приношу свои извинения за неправильное чтение!

3
ответ дан 24 November 2019 в 19:20
поделиться

Сделайте JournalEntry частным вложенным типом . Любые общедоступные члены будут видны только включающему типу.

public class Journal
{
    private class JournalEntry
    {
    }
}

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

public interface IJournalEntry
{
}

public class Journal
{
    public IEnumerable<IJournalEntry> Entries
    {
        get { ... }
    }

    private class JournalEntry : IJournalEntry
    {
    }
}
20
ответ дан 24 November 2019 в 19:20
поделиться
Другие вопросы по тегам:

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