- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
class Program
{
class A
{
//-----------------------------------------------------------------------
public static A CurrentRoot;
public static Dictionary<object, A> RootMap = new Dictionary<object, A>();
public static object Lock = new object();
//-----------------------------------------------------------------------
public int Test;
public A()
{
lock (Lock)
{
CurrentRoot = this;
b = new B();
}
}
internal class B
{
public B() { RootMap.Add(this, CurrentRoot); }
public A root { get { return RootMap[this]; } }
~B() { RootMap.Remove(this); }
}
public B b;
}
static void Main(string[] args)
{
A a1 = new A(); a1.Test = 555;
A a2 = new A(); a2.Test = 888;
Console.WriteLine(a1.b.root.Test); Console.WriteLine(a1.Test);
Console.WriteLine(a2.b.root.Test); Console.WriteLine(a2.Test);
Console.WriteLine(a1.b.root.b.root.b.root.b.root.b.root.Test);
}
Класс создан для того чтобы вложенные структуры имели доступ к структуре родителя. Safe thread support.
Dummy00001 20.09.2014 16:58 # 0
меня убивает что ни один язык/фрэймворк не позволяет этого сделать из коробки.
только не надо мне опять эти теории толкать что это "теоретически неправильно".
на практике бывает нужно, и доморощеные реализации часто обращаются в ГК монументального характера.
kegdan 20.09.2014 17:36 # 0
Dummy00001 20.09.2014 18:00 # 0
повседневные примеры тоже легко найти.
возьми любую GUI библиотеку. каждый раз когда ты создаешь контрол, ему параметром надо передать парент окно. теоретически, контролу парент в ж не нужен. но практически, контрол наследует бэкграунд от парента, рисует себя в контексте парента, и получает события от парента.
Xom94ok 20.09.2014 18:50 # 0
Пример не очень ИМХО, т.к. предок контрола рисует свой фон и контрол. А контрол просто уведомляет, что он "грязный" и его нужно перерисовать. Да и знать структуру родителя контролу тоже незачем.
Мне этот "доступ вложенной структуры к структуре родителя" напоминает сишный offsetof. Вроде, полезный, но хак.
Dummy00001 20.09.2014 19:14 # 0
и да и нет. проблема в том что бы вложеная структура могла узнать что (1) она вложеная, (2) и если она вложеная то во что.
offsetof() как раз и не работает, потому что нужно знать заранее что во что вложено. иначе не работает.
Xom94ok 20.09.2014 19:58 # 0
В шарпике мб через рефлексию можно что-то соорудить. Я почти уверен, что в языке D есть конструкция, удовлетворяющая всем требованиям, да ещё и в compile time.
Dummy00001 20.09.2014 20:24 # 0
преимущество жабы (и шарпа?) здесь в том что объект есть всегда указатель. в крестах же есть еще грабли что у тебя вложеная структура может быть (1) частью родительского объекта, или (2) родитель может на нее иметь только указатель.
Dummy00001 20.09.2014 18:06 # 0
bormand 20.09.2014 21:14 # 0
Почему бы просто не передать ссылку на родителя в конструктор?
Dummy00001 20.09.2014 21:28 # 0
`static StaticEntity static_entity;` - и у тебя все 50 полей проинициализированы нулями. не идеально - но работает.
теперь представь себе теперь добавление конструктора, и последующее добавление 50 инициализаторов для этих полей. и это все только что бы передать один гребаный параметр - который к слову компилеру известен.
bormand 20.09.2014 21:42 # 0
1) Помечаем класс как "имеющий ссылку на его владельца". От этого у него внутри появляется неявный указатель некого типа, а у конструктора возникает неявный параметр.
2) Экземпляр данного класса нельзя использовать без владельца (т.е. размещение на стеке или через new запрещено (как вариант - разрешено, просто указатель будет null'ом, еще вариант - можно самому передать как параметр в new или конструктор).
3) Владелец, во время конструирования, передает туда указатель на себя. При этом, если тип владельца не кастуется в тип неявного указателя - возникает ошибка компиляции.
4) Теперь объект может юзать неявный указатель на владельца, при необходимости раскастовывая его во что нужно.
> все 50 полей проинициализированы нулями
Имхо, зависеть от способа создания объекта - ССЗБ. Сегодня он в статике, и там нули. Завтра его создали на стеке или в куче - и кровь-кишки-распидорасило. Я сразу бы написал 50 инициализаторов, чтобы спать спокойно.
kegdan 21.09.2014 00:39 # 0
wvxvw 21.09.2014 09:06 # 0
bormand 21.09.2014 09:09 # 0
kegdan 20.09.2014 17:55 # 0
в данной ситуации данный код отсасывает простому
guest 20.09.2014 18:07 # 0
kegdan 20.09.2014 18:17 # 0
guest 20.09.2014 18:35 # 0
kegdan 20.09.2014 18:51 # 0
Рут лежит в B, а идешь ты по массиву А.
И даже если бы шел по массиву B какая разница сколько полей если ты размер задаешь не руками а получаешь рефлексией?
Почему бы не юзать сериализацию?
guest 20.09.2014 18:36 # 0
cyperh 22.09.2014 10:35 # 0
Ты сам то понимаешь что ты говоришь? Сам себе противоречишь. Если ты имел ввиду что при создании сложных вложенных структур ты хочешь иметь к ним доступ, не прибегая к бесконечным итерациям по коллекциям, то юзай фабрику в которой будут храниться в каком то виде иерархия созданных объектов
guest 20.09.2014 19:10 # 0
Не знаю почему такую простую вещь до сих пор не организовали.
dzzpchelka 23.09.2014 08:07 # 0
kegdan 23.09.2014 09:32 # 0
dzzpchelka 23.09.2014 09:40 # +1
kegdan 23.09.2014 09:44 # 0
dzzpchelka 23.09.2014 09:48 # 0
Vasiliy 24.09.2014 15:55 # 0
kegdan 24.09.2014 15:58 # 0
Vasiliy 24.09.2014 16:08 # +3
kegdan 24.09.2014 17:41 # 0
Vasiliy 24.09.2014 20:01 # 0
bormand 23.09.2014 09:49 # 0