Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
August 28, 2017 Accessing outer class attribute from inner struct | ||||
---|---|---|---|---|
| ||||
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é |
August 28, 2017 Re: Accessing outer class attribute from inner struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | 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 |
August 28, 2017 Re: Accessing outer class attribute from inner struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Moritz Maxeiner | 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:
>> [...]
>>
>> 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
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é
|
August 28, 2017 Re: Accessing outer class attribute from inner struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | 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:
>> 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
>
> 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.
---
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.
|
August 29, 2017 Re: Accessing outer class attribute from inner struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Moritz Maxeiner | 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é |
August 29, 2017 Re: Accessing outer class attribute from inner struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | 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: >> >> 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 :) 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. > [...] > > 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 |
August 29, 2017 Re: Accessing outer class attribute from inner struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Moritz Maxeiner | 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:
>> 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 :)
>
> 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.
>
>> [...]
>>
>> 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
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é
|
Copyright © 1999-2021 by the D Language Foundation