Почему / когда вы должны использовать вложенные классы в .net? Или ты не должен? - PullRequest
89 голосов
/ 08 сентября 2008

В недавнем блоге Кэтлин Доллард она представляет интересную причину использования вложенных классов в .net. Тем не менее, она также упоминает, что FxCop не любит вложенные классы. Я предполагаю, что люди, пишущие правила FxCop, не глупы, так что за этой позицией должны быть аргументы, но я не смог ее найти.

Ответы [ 13 ]

0 голосов
/ 20 декабря 2014

Мне нравится вкладывать исключения, которые являются уникальными для одного класса, т.е. те, которые никогда не выбрасывают из других мест.

Например:

public class MyClass
{
    void DoStuff()
    {
        if (!someArbitraryCondition)
        {
            // This is the only class from which OhNoException is thrown
            throw new OhNoException(
                "Oh no! Some arbitrary condition was not satisfied!");
        }
        // Do other stuff
    }

    public class OhNoException : Exception
    {
        // Constructors calling base()
    }
}

Это помогает сохранить ваши файлы проекта аккуратными и не полными сотен маленьких классных исключений.

0 голосов
/ 31 октября 2013

Поскольку nawfal упомянул реализацию шаблона абстрактной фабрики, этот код может быть расширен для достижения шаблона кластеров классов , который основан на шаблоне абстрактной фабрики.

0 голосов
/ 19 апреля 2013

Я часто использую вложенные классы, чтобы скрыть детали реализации. Пример ответа Эрика Липперта здесь:

abstract public class BankAccount
{
    private BankAccount() { }
    // Now no one else can extend BankAccount because a derived class
    // must be able to call a constructor, but all the constructors are
    // private!
    private sealed class ChequingAccount : BankAccount { ... }
    public static BankAccount MakeChequingAccount() { return new ChequingAccount(); }
    private sealed class SavingsAccount : BankAccount { ... }
}

Этот шаблон становится еще лучше с использованием обобщений. См. этот вопрос для двух интересных примеров. В итоге я пишу

Equality<Person>.CreateComparer(p => p.Id);

вместо

new EqualityComparer<Person, int>(p => p.Id);

Также у меня может быть общий список Equality<Person>, но не EqualityComparer<Person, int>

var l = new List<Equality<Person>> 
        { 
         Equality<Person>.CreateComparer(p => p.Id),
         Equality<Person>.CreateComparer(p => p.Name) 
        }

где как

var l = new List<EqualityComparer<Person, ??>>> 
        { 
         new EqualityComparer<Person, int>>(p => p.Id),
         new EqualityComparer<Person, string>>(p => p.Name) 
        }

невозможно. Это преимущество наследования вложенного класса от родительского класса.

Другой случай (такой же природы - скрытие реализации) - это когда вы хотите сделать члены класса (поля, свойства и т. Д.) Доступными только для одного класса:

public class Outer 
{
   class Inner //private class
   {
       public int Field; //public field
   }

   static inner = new Inner { Field = -1 }; // Field is accessible here, but in no other class
}
...