C # вложенный класс / структура видимости - PullRequest
3 голосов
/ 30 июня 2011

Я пытаюсь выяснить, каков правильный синтаксис для достижения определенной цели API, однако я борюсь с видимостью.

Я хочу иметь возможность доступа к члену Messenger экземпляра, например msgr.Title.ForSuccesses.

Однако я не хочу иметь возможность создавать экземпляр Messenger.Titles за пределами моего Messenger класса.

Я также готов сделать Messenger.Titles структурой.

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

Ответы [ 4 ]

7 голосов
/ 30 июня 2011

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


class Program {
    static void Main(string[] args) {
        var m = new Messenger { Title = { ForErrors = "An unexpected error occurred ..." } }; // this is allowed
        var t = new Messenger.Titles(); // this is NOT allowed
    }
}

public class Messenger {
    public interface ITitles {
        string ForSuccesses { get; set; }
        string ForNotifications { get; set; }
        string ForWarnings { get; set; }
        string ForErrors { get; set; }
    }

    private class Titles : ITitles {
        public string ForSuccesses { get; set; }
        public string ForNotifications { get; set; }
        public string ForWarnings { get; set; }
        public string ForErrors { get; set; }
    }

    public ITitles Title { get; private set; }
    public Messenger() {
        Title = new Titles();
    }
}

0 голосов
/ 30 июня 2011

Ну, вы можете сделать Titles структурой и сделать конструктор открытым или внутренним.Таким образом, каждый раз, когда клиент получает копию экземпляра Titles через свойство Title, он получает значение, а не ссылку.Они могут изменить это значение, но, чтобы применить это изменение к внутреннему состоянию вашего объекта, им потребуется иметь возможность снова установить значение через свойство Title.Они не могут, потому что у вас Установщик титров помечен как частный.

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

// Your constructor...
public Messenger()
{
    Titles t = new Titles();
    t.ForSuccesses = "blah";
    Title = t;
}

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

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

0 голосов
/ 30 июня 2011

Зачем мне нужно использовать вложенные классы C # Вложенный тип никогда не предназначен для инициализации из внешнего типа.

0 голосов
/ 30 июня 2011

Если вы сделаете конструктор Titles internal, вы сможете создавать его экземпляры только в вашей сборке.Если это API, возможно, это будет достаточно защищено?Вы можете увидеть этот шаблон в BCL (например, HttpWebRequest, который может быть создан только через вызовы WebRequest.Create).

...