Вопрос о нестатических членах одиночного элемента (C#)

L2 = [o for k in [[j] if not isinstance(j,list) else j for j in [k for i in [[m] if not 
isinstance(m,list) else m for m in L] for k in i]] for o in k]
7
задан TheVillageIdiot 6 July 2009 в 18:12
поделиться

8 ответов

Когда вы создаете синглтон, вы создаете единственный статический экземпляр нестатического типа.

В этом случае ваш тип (класс A) содержит ссылку на другой тип (Класс B). Статический экземпляр будет содержать единственную ссылку на единственный экземпляр объекта класса B. Технически он не является «статическим», но поскольку он привязан к статическому объекту (экземпляру класса A), он будет вести себя как статическая переменная. У вас всегда будет один и только один объект класса B (на который указывает ваш экземпляр класса A). Вы никогда не создадите более одного экземпляра класса B внутри класса A.

Однако нет ничего, что препятствовало бы созданию второго экземпляра класса B в другом месте - это был бы другой экземпляр.

11
ответ дан 6 December 2019 в 10:02
поделиться

_classB является экземпляром (не статическим) членом ClassA. Каждый экземпляр ClassA будет иметь один экземпляр _classB (с учетом написанного вами инициализатора поля). Итак, если вы используете шаблон Singleton для доступа к ClassA и, следовательно, всегда имеете (максимум) один загруженный экземпляр ClassA, у вас всегда будет (максимум) один экземпляр ClassB, загруженный посредством ClassA.

Теперь, поскольку ClassB имеет общедоступный конструктор по умолчанию, что-то еще может создавать экземпляры самостоятельно. Если это вызывает беспокойство, подумайте о том, чтобы сделать класс ClassB закрытым. Кроме того, поскольку ClassA имеет общедоступный конструктор по умолчанию, ничто не мешает людям создавать столько экземпляров, сколько они хотят. Вы можете сделать конструктор no-arg закрытым:

private ClassA() {}
3
ответ дан 6 December 2019 в 10:02
поделиться

Имея такое объявление:

private ClassB _classB = new ClassB();

Вы создаете экземпляр _classB для нового экземпляра ClassB всякий раз, когда вызывается конструктор ClassA.

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

Это гарантирует, что _classB будет обновлен только один раз, но не -статический. Однако, если кто-то изменит ClassA, чтобы он больше не был синглтоном в будущем, вы начнете создавать несколько экземпляров ClassB. Если бы _classB был действительно статическим, то этого не было бы.

2
ответ дан 6 December 2019 в 10:02
поделиться

Одноэлементный шаблон гарантирует, что только один экземпляр ClassB будет доступный из одноэлементного экземпляра ClassA в любое время. Весь смысл шаблона singleton в том, что он гарантирует, что только один экземпляр ClassA доступен в любое время, таким образом, только одна ссылка на _classB (хотя, поскольку ClassA является изменяемым, эта ссылка может измениться).

Однако обратите внимание, что область из ClassB по-прежнему является уровнем экземпляра, а не статическим уровнем. Компилятор никогда не сделает ничего настолько странного, чтобы использовать спецификатор области, отличный от указанного вами. Вы по-прежнему должны обращаться к ссылке на ClassB через экземпляр, независимо от того, используете ли вы синглтон.

2
ответ дан 6 December 2019 в 10:02
поделиться

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

На мой взгляд, всегда лучше писать четкий код, который показывает вам все намерения. Таким образом, следующему человеку, который будет работать над вашим кодом, не придется играть в угадайку, чтобы определить, что вы хотите сделать.

0
ответ дан 6 December 2019 в 10:02
поделиться

_classB не статичен; экземпляр ClassA содержит ссылку на экземпляр _classB; если экземпляр ClassA является статическим (как в одноэлементном экземпляре), то он все равно будет содержать ссылку на _classB, но новые экземпляры ClassA будут содержать РАЗНЫЕ ссылки на (потенциально) разные экземпляры _classB. Поэтому, если вы ссылаетесь на один и тот же экземпляр ClassA (через шаблон singleton), вы все равно получите тот же экземпляр _classB; но если вы создадите новый экземпляр ClassA, вы получите другой экземпляр _classB, поэтому _classB не является статическим.

0
ответ дан 6 December 2019 в 10:02
поделиться

Как определено ClassA нарушает определение singleton. Представьте, что два потока одновременно вызывают статическое свойство Instance. Поскольку доступ не синхронизирован, вы можете получить два разных экземпляра ClassA и, следовательно, два разных экземпляра ClassB.

  1. Thread1 вызывает свойство Instance, а поскольку _classA имеет значение null, он входит в метод LoadClassA
  2. Thread2 вызывает свойство Instance и как _classA все еще равно нулю, он входит в метод LoadClassA
  3. Thread1 и Thread2 получают два разных экземпляра ClassA
1
ответ дан 6 December 2019 в 10:02
поделиться

Поскольку ClassA является одноэлементным, в вашем приложении есть только один его экземпляр. Внутри этого экземпляра класса есть член для хранения переменной ClassB. После инициализации этой переменной это переменная экземпляра, но поскольку у вас есть только 1 экземпляр ClassA, вы всегда будете получать один и тот же экземпляр ClassB.

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

private static ClassA _instance = new ClassA();

private ClassA() {}

public static ClassA Insance { get { return _instance; } }

без ленивой загрузки и немедленной инициализации вы обеспечиваете безопасность потоков.

0
ответ дан 6 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: