digitalmars.D.learn - Accessing outer class attribute from inner struct
- Andre Pany (33/33) Aug 28 2017 Hi,
- Moritz Maxeiner (28/35) Aug 28 2017 Add an explicit class reference member to to it:
- Andre Pany (9/47) Aug 28 2017 Unfortunately thats not possible. ColumnsArray and the attribute
- Moritz Maxeiner (29/80) Aug 28 2017 ---
- Andre Pany (23/28) Aug 29 2017 Thanks for the explanation. I now tried to use a class and use a
- Moritz Maxeiner (12/25) Aug 29 2017 A nested class' outer property (when nested inside another class)
- Andre Pany (7/35) Aug 29 2017 I think I found a solution which fulfills all goals but I have to
Hi, I build some framework to access Delphi components from D. Delphi supports property array access "StringGrid1.Columns[2]" which is translated in Delphi to a private method call "GetColumn(2)". I need to imitate this behavior in my D code. Therefore my TCustomGrid class has a inner struct ColumnsArray with an opIndex. While accessing opIndex I need to call a DLL method. Therefore I need the "reference" attribute which is available in my TCustomGrid via inheritance. To make my question short:) If ColumnsArray is a class I can access the attribute "reference" but not if it is a struct. I would rather prefer a struct, but with a struct it seems I cannot access "reference". How can I access "reference" from my inner struct? class TCustomGrid: TCustomPresentedScrollBox { struct ColumnsArray { TColumn opIndex(int index) { int r = getIntegerIndexedPropertyReference(reference, "Columns", index); return new TColumn(r); } } ColumnsArray Columns; ... } Kind regards André
Aug 28 2017
On Monday, 28 August 2017 at 21:52:58 UTC, Andre Pany wrote:[...] To make my question short:) If ColumnsArray is a class I can access the attribute "reference" but not if it is a struct. I would rather prefer a struct, but with a struct it seems I cannot access "reference". How can I access "reference" from my inner struct? [...]Add an explicit class reference member to to it: --- class TCustomGrid: TCustomPresentedScrollBox { struct ColumnsArray { TCustomGrid parent; TColumn opIndex(int index) { int r = getIntegerIndexedPropertyReference(reference, "Columns", index); return new TColumn(r); } } ColumnsArray Columns; this() { Columns = ColumnsArray(this); } ... } --- Nesting structs inside anything other than functions[1] is for visibility/protection encapsulation and namespacing only. [1] non-static structs in functions are special as they have access to the surrounding stack frame
Aug 28 2017
On Monday, 28 August 2017 at 22:28:18 UTC, Moritz Maxeiner wrote:On Monday, 28 August 2017 at 21:52:58 UTC, Andre Pany wrote:Unfortunately thats not possible. ColumnsArray and the attribute will become a string mixin to avoid boilerplate. It would be error prone if I have to initialize them in the constructor too. I want just 1 single coding line for this property. That is also the reason I do not want to use a class, as I would have to initialize them in the constructor. Kind regards André[...] To make my question short:) If ColumnsArray is a class I can access the attribute "reference" but not if it is a struct. I would rather prefer a struct, but with a struct it seems I cannot access "reference". How can I access "reference" from my inner struct? [...]Add an explicit class reference member to to it: --- class TCustomGrid: TCustomPresentedScrollBox { struct ColumnsArray { TCustomGrid parent; TColumn opIndex(int index) { int r = getIntegerIndexedPropertyReference(reference, "Columns", index); return new TColumn(r); } } ColumnsArray Columns; this() { Columns = ColumnsArray(this); } ... } --- Nesting structs inside anything other than functions[1] is for visibility/protection encapsulation and namespacing only. [1] non-static structs in functions are special as they have access to the surrounding stack frame
Aug 28 2017
On Monday, 28 August 2017 at 22:47:12 UTC, Andre Pany wrote:On Monday, 28 August 2017 at 22:28:18 UTC, Moritz Maxeiner wrote:--- class C { struct S { } S s; } --- is semantically equivalent to --- struct S { } class C { S s; } --- with the two differences being - namespacing (outside of C one has to use C.S to access S) - you can protect the visibility of the S from outside the module C resides in via private,public, etc. In both cases S doesn't inherently how about C, which means a solution using default initialization is not feasible, as S.init can't know about any particular instance of C. I don't think there's any way for you to avoid using a class constructor.On Monday, 28 August 2017 at 21:52:58 UTC, Andre Pany wrote:Unfortunately thats not possible. ColumnsArray and the attribute will become a string mixin to avoid boilerplate. It would be error prone if I have to initialize them in the constructor too. I want just 1 single coding line for this property. That is also the reason I do not want to use a class, as I would have to initialize them in the constructor.[...] To make my question short:) If ColumnsArray is a class I can access the attribute "reference" but not if it is a struct. I would rather prefer a struct, but with a struct it seems I cannot access "reference". How can I access "reference" from my inner struct? [...]Add an explicit class reference member to to it: --- class TCustomGrid: TCustomPresentedScrollBox { struct ColumnsArray { TCustomGrid parent; TColumn opIndex(int index) { int r = getIntegerIndexedPropertyReference(reference, "Columns", index); return new TColumn(r); } } ColumnsArray Columns; this() { Columns = ColumnsArray(this); } ... } --- Nesting structs inside anything other than functions[1] is for visibility/protection encapsulation and namespacing only. [1] non-static structs in functions are special as they have access to the surrounding stack frame
Aug 28 2017
On Monday, 28 August 2017 at 23:12:40 UTC, Moritz Maxeiner wrote:In both cases S doesn't inherently how about C, which means a solution using default initialization is not feasible, as S.init can't know about any particular instance of C. I don't think there's any way for you to avoid using a class constructor.Thanks for the explanation. I now tried to use a class and use a static opIndex. But it seems from a static method you also cannot access the attributes of a outer class :) class TCustomGrid: TCustomPresentedScrollBox { class ColumnsArray { static TColumn opIndex(int index) { // Reference is defined in TCustomGrid via inheritene int r = getIntegerIndexedPropertyReference(reference, "Columns", index); return new TColumn(r); } } alias Columns = ColumnsArray; ... } This seems like an unnecessary limitation... Kind regards André
Aug 29 2017
On Tuesday, 29 August 2017 at 07:59:40 UTC, Andre Pany wrote:On Monday, 28 August 2017 at 23:12:40 UTC, Moritz Maxeiner wrote:A nested class' outer property (when nested inside another class) is a class reference, which means we not only require a class instance of the outer class to reference, but also a class instance of the nested class to store said class reference to the other class in. A static class method (by definition) is invoked without a class instance. The two are inherently incompatible.In both cases S doesn't inherently how about C, which means a solution using default initialization is not feasible, as S.init can't know about any particular instance of C. I don't think there's any way for you to avoid using a class constructor.Thanks for the explanation. I now tried to use a class and use a static opIndex. But it seems from a static method you also cannot access the attributes of a outer class :)[...] This seems like an unnecessary limitation...I can only recommend reading the language specification w.r.t, nested classes [1] if it seems that way to you, because it is not. [1] https://dlang.org/spec/class.html#nested
Aug 29 2017
On Tuesday, 29 August 2017 at 08:30:24 UTC, Moritz Maxeiner wrote:On Tuesday, 29 August 2017 at 07:59:40 UTC, Andre Pany wrote:I think I found a solution which fulfills all goals but I have to try it out. A property method "Columns" will return an initialized struct "ColumnsArray" as proposed by you. This should nicely work as string mixin. Thanks for your help. Kind regards AndréOn Monday, 28 August 2017 at 23:12:40 UTC, Moritz Maxeiner wrote:A nested class' outer property (when nested inside another class) is a class reference, which means we not only require a class instance of the outer class to reference, but also a class instance of the nested class to store said class reference to the other class in. A static class method (by definition) is invoked without a class instance. The two are inherently incompatible.In both cases S doesn't inherently how about C, which means a solution using default initialization is not feasible, as S.init can't know about any particular instance of C. I don't think there's any way for you to avoid using a class constructor.Thanks for the explanation. I now tried to use a class and use a static opIndex. But it seems from a static method you also cannot access the attributes of a outer class :)[...] This seems like an unnecessary limitation...I can only recommend reading the language specification w.r.t, nested classes [1] if it seems that way to you, because it is not. [1] https://dlang.org/spec/class.html#nested
Aug 29 2017