Скажем, если у меня есть раскрывающийся список в форме, и у меня есть другой вложенный класс внутри этого класса. Теперь, какой лучший способ получить доступ к этому выпадающему списку из вложенного класса?
Каков наилучший способ доступа к полю в охватывающем классе из вложенного класса?
Ответ 1
В отличие от Java, вложенный класс не является специальным "внутренним классом", поэтому вам нужно будет передать ссылку. У Раймонда Чена есть пример, описывающий различия: вложенные классы С# похожи на вложенные классы C++, а не на внутренние классы Java.
Вот пример, где конструктору вложенного класса передается экземпляр внешнего класса для последующей ссылки.
// C#
class OuterClass
{
string s;
// ...
class InnerClass
{
OuterClass o_;
public InnerClass(OuterClass o) { o_ = o; }
public string GetOuterString() { return o_.s; }
}
void SomeFunction() {
InnerClass i = new InnerClass(this);
i.GetOuterString();
}
}
Обратите внимание, что InnerClass может получить доступ к " s
" OuterClass, я не изменял код Рэймонда (как я упоминал выше), поэтому помните, что " string s;
" является private
потому что никакие другие права доступа не были указаны.
Ответ 2
Вложенные типы не похожи на внутренние классы в Java - нет встроенного экземпляра содержащего типа. (Они больше похожи на статические вложенные классы в Java.) Они фактически являются отдельными классами с двумя отличиями:
- Если тип содержимого является общим, вложенный тип эффективно параметризуется с помощью содержащего типа, например.
Outer<int>.Nested
не совпадает сOuter<string>.Nested
. - Вложенные типы имеют доступ к закрытым членам в содержащем типе.
Ответ 3
В отличие от Java, в С# нет неявной ссылки на экземпляр класса-оболочки.
Вам нужно передать такую ссылку на вложенный класс. Типичный способ сделать это через встроенный конструктор классов.
public partial class Form1 : Form
{
private Nested m_Nested;
public Form1()
{
InitializeComponent();
m_Nested = new Nested(this);
m_Nested.Test();
}
private class Nested
{
private Form1 m_Parent;
protected Form1 Parent
{
get
{
return m_Parent;
}
}
public Nested(Form1 parent)
{
m_Parent = parent;
}
public void Test()
{
this.Parent.textBox1.Text = "Testing access to parent Form control";
}
}
}
Ответ 4
Статические члены
Поскольку никто не упомянул об этом до сих пор: в зависимости от вашей ситуации, если переменная-член также может быть static, вы можете просто получить к ней доступ следующим образом.
class OuterClass
{
private static int memberVar;
class NestedClass
{
void SomeFunction() { OuterClass.memberVar = 42; }
}
}
Sidenote: Я обозначил memberVar
целенаправленно (и избыточно) как private
, чтобы проиллюстрировать данную способность вложенного класса получить доступ к закрытым членам этого внешнего класса.
Внимание/Пожалуйста, рассмотрите
В некоторых ситуациях это может быть самый простой способ/обходной путь для доступа, но...
-
Статичность также означает, что переменная будет разделяться между всеми объектами экземпляра со всеми минусами/последствиями (безопасность потоков и т.д.).
-
Static также означает, что это, очевидно, не будет работать, если у вас есть несколько экземпляров родительского класса, и переменная должна содержать индивидуальное значение для каждого экземпляра
Поэтому в большинстве случаев вы можете пойти с другим подходом...
Передача справки
Как большинство людей предложили (и потому что это также самый правильный ответ), здесь приведен пример передачи ссылки на экземпляр внешнего класса.
class OuterClass
{
private int memberVar;
private NestedClass n;
OuterClass() { n = new NestedClass(this); }
class NestedClass
{
private OuterClass parent;
NestedClass(OuterClass p) { parent = p; }
SomeFunction() { parent.memberVar = 42; }
}
}
Ответ 5
Еще один метод, полезный при определенных обстоятельствах, заключается в том, чтобы вывести вложенный класс из внешнего класса. Например:
class Outer()
{
protected int outerVar;
class Nested() : Outer
{
//can access outerVar here, without the need for a
// reference variable (or the associated dot notation).
}
}
Я использовал этот метод, особенно в контексте Структурированные модульные тесты. (Это может не относиться к конкретному вопросу OP, но это может быть полезно для вложенных классов в целом, как в случае с этим "повторяющимся" вопросом: "Могу ли я получить доступ к объектам внешнего класса во внутреннем классе" )
Ответ 6
Исправьте меня, если я ошибаюсь, вы пытаетесь обработать внешний контроль из внутреннего класса, следовательно, вы столкнулись с этим. Лучшим способом сделать это будет обработка дел в режиме, управляемом событиями. Используйте шаблон Observer, зарегистрируйте прослушиватель на внешнем элементе управления (ваш вложенный/внутренний класс будет слушателем). Делает жизнь проще. Я боюсь, что это не тот ответ, который вы ожидали!
Ответ 7
Вы можете передать охватывающий класс в качестве параметра в конструктор вложенного класса, например:
private NestedClass _nestedClass;
public ParentClass()
{
_nestedClass = new NestedClass(this);
}
Вложенные классы обычно не рекомендуются и должны быть закрытыми и/или внутренними. Они, на мой взгляд, иногда полезны.
Ответ 8
отправить мастер-класс в качестве параметра конструктора во вложенный (внутренний) класс.