Вложенные типы или другое решение для сопоставленных классов один к одному - PullRequest
3 голосов
/ 06 января 2011

У меня есть класс, который нуждается в некоторой функциональности для инкапсуляции.

Я думал о вложенном классе и включил в него эту функциональность и некоторые состояния. Отношение между этими двумя классами однозначно.

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

Какая лучшая практика для моей проблемы?

Ответы [ 3 ]

1 голос
/ 06 января 2011

У нас была точно такая же проблема около 6 месяцев назад, но по другой причине.У нас было около 20 «обычных» классов и один гигантский класс размером с Юпитер, который делал много, слишком много, и его нужно было разбить.

На самом деле нам нужны ДВА ребенка, в дополнение к родителю, соба ребенка в отношении 1: 1 к родителю.

Первая попытка (которая сработала) использовала шаблон старой школы для передачи ссылки «this» в конструктор каждого дочернего элемента, изатем используйте метод .Parent для перехода назад.Это было кошмаром из-за проблем с GC, и мы искали лучшее решение в короткие сроки.

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

Итак, это будет моя рекомендация:

Parent
 |
 +-Child1
 |
 +-Child2

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

На самом деле это очень похоже на способ разработки ADO.Net с независимыми объектами, которые принимают ссылки на каждый из них.другие в методах, где они необходимы.

1 голос
/ 06 января 2011

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

Так что это действительно зависит от вашей конкретной ситуации, но необходимо учитывать следующее:

  1. Будет ли вложенный класс публично видимым?Они громоздки из-за синтаксиса, который потребители должны использовать для ссылки на вложенный тип: OuterType + InnerType

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

  3. Анализ кода в Visual Studio будет громко жаловаться на общедоступные вложенные классы (они не считаются хорошей формой со стороны руководства по разработке структуры)), поэтому, если вы используете FxCop, вам нужно будет делать исключения.

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

0 голосов
/ 06 января 2011
using System;

class OuterType
{
    private static OuterType _instance;

    public OuterType()
    {
        _instance = this;
    }

    private String Message
    {
        get { return "Hello from OuterType"; }
    }

    public void testInnerType()
    {
        InnerType innerType = new InnerType();
        Console.WriteLine(innerType.FormattedOutertMessage);
    }

    private class InnerType
    {
        private readonly OuterType _outerType = _instance;

        public String FormattedOutertMessage
        {
            get { return _outerType.Message.ToUpper(); }
        }
        // InnerType doesn't need to dispose any object of OuterType.
    }
}

Тогда это работает так:

class Program
{
    static void Main(string[] args)
    {
        OuterType outerType = new OuterType();
        outerType.testInnerType();
        Console.ReadKey();
    }
}

Но я не уверен, хорошая ли это идея или нет ?!

...