2013-02-27 4 views
3

Я пытаюсь изучить о вложенном классе в C#. Прочитав много документов и очков, я все еще не понял, когда использовать вложенные классы. Но насколько я понимаю, я сделал небольшую пробную программу. Я вставляю свой код ниже. Является ли эта вложенная программа класса реализована в правильной логике? , Что на самом деле вложенный класс используется для?. а также я сомневаюсь в этой программе, и я уточнил это сомнение в программе. Пожалуйста, помогите мне ...Вложенный класс в C#

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     Bank bankObj = new Bank(); 
     bankObj.CreateAccount(); 
     bankObj.ShowMyAccountNumber(); 
    } 
} 

class Bank 
{ 
    static int accountNumber; // here if I just declare this as int accountNumber without static it showing an error in the CreatePersonalAccount(int accNo) method's first line ie accountNumber = accNo; as "Cannot access a non-static member of outer type." What actually this error mean ? 

    public class BankAccountSection 
    { 
     public bool CreatePersonalAccount(int accNo) 
     { 
      accountNumber = accNo; 
      return true; 
     } 
    } 

    public void CreateAccount() 
    { 
     bool result = new BankAccountSection().CreatePersonalAccount(10001); 
    } 

    public void ShowMyAccountNumber() 
    { 
     MessageBox.Show(accountNumber.ToString()); 
    } 
} 
+0

Ваш код не отображает вложенный класс вообще. Он имеет два отдельных класса верхнего уровня. –

+4

@Jon, 'BankAccountSection' вложен внутри' Bank' –

+1

Imo/ime мало пользы для вложенных классов –

ответ

7

Вложенные классы обычно используются для небольших классов полезности, которые не могут использоваться вне окружающего (внешнего) класса. По этой причине вложенные классы обычно равны private. (Там даже FxCop rule для этого.)

Ваш код

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

Что касается static int accountNumber;: Это сделает accountNumber общее поле через все объектов банка, который побеждает всю цель. Не делай этого. Если вам действительно нужно установить поле объекта Bank внутри внутреннего класса, вам необходимо передать ссылку объекта Bank во внутренний класс. (Это отличается от Java, где такая ссылка доступна автоматически при некоторых обстоятельствах.) В вашем конкретном случае просто избавляйтесь от внутреннего класса.

Примеры законных случаев использования

  • У вас есть большой алгоритм внутри метода. Вы понимаете, что извлечение этого алгоритма в собственный класс с использованием множества небольших методов и переменных экземпляра повысит читаемость. Поскольку алгоритм очень специфичен и, вероятно, не полезен для других классов, вы помещаете алгоритм во внутренний класс. Таким образом, вы избегаете загромождения своего внешнего класса переменными экземпляра, которые используются только этим алгоритмом.
  • Вы создаете структуру данных списка, которая внутренне реализована как linked list.Поскольку вы не раскрываете узлы списка во внешнем мире, вы делаете узлы внутренним классом.

Похожие:

+0

Я бы предположил, что если 'Thing' определяет тип, экземпляры которого будут существовать, чтобы действовать на конкретный экземпляр, имеющий тип' Thing.Frobber', передает это отношение гораздо более четко, чем 'ThingFrobber'. Это особенно верно во многих ситуациях, связанных с дженериками. 'List .Enumerator' понятнее, чем будет' ListEnumerator '. Кроме того, в некоторых случаях, связанных с такими вещами, как адаптеры, 'Name1 .Name2 ' может выражать отношения между типами более чисто, чем 'Name '. – supercat

+0

Заметим также, что если вы хотите вызвать общий метод таким образом, чтобы указать некоторые параметры, но не другие, это можно сделать, если статический класс 'ClassName ' содержит метод 'MethodName (U param)'. Я не знаю лучшего способа разрешить некоторые, но не все общие типы методов. – supercat

0

Вы, кажется, думаете, что вложенные классы на C# ведут себя так же, как в Java. Другими словами, если только вложенный класс не объявлен как статический, то он будет совместно использовать экземпляр охватывающего класса. В C# это не так. В C# такого типа вещей нет, все вложенные классы неявно статичны.

Вот почему вы не можете получить доступ к accountNumber из вложенного класса, если это поле не объявлено статическим. (Поскольку вложенный класс не имеет доступа к какому-либо конкретному экземпляру). Идомное решение этой проблемы в C# - передать экземпляр охватывающего класса во вложенный класс (предположительно, передав this через аргумент конструктора при его создании).

+0

Вы говорите, что 'BankAccountSection' неявно статичен - то есть он может иметь только статические члены? 'CreatePersonalAccount' не объявляется как' static' в приведенном примере. –

+0

Нет, я говорю, что это не «класс экземпляра» (который не имеет аналога в C#, но * существует * в Java) –

0

Во-первых, это не вложенный класс, это всего лишь два класса в одном файле.

Теперь, даже если это был вложенный класс, это, вероятно, будет примером того, когда НЕ использовать вложенные классы. Вы обязательно должны отделить свою логику от логики GUI.

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

+3

OP действительно показал вложенный класс. –

0

Ошибка в том, что вы не можете получить доступ к члену, не статического класса без его объекта. , если вы это сделаете, тогда он должен быть объявлен статическим.

Смежные вопросы