Thread overview
Private nested class instance accessed via outer class public interface
Jun 16, 2023
Murloc
Jun 16, 2023
Murloc
Jun 16, 2023
Anonymouse
Jun 16, 2023
Murloc
June 16, 2023

I'm not sure if this behavior is desired and have any use-cases (should I report it as a bug?), but, for example, C# doesn't allow this.

import std.conv;

class Outer {
    private static class Inner {
        private int field = 30;
        override string toString() => to!string(field);
    }
    static Inner getInner() {
        return new Inner();
    }
}
import std.stdio: writeln;
import classes; // the file above

void main() {
    // Here I have an object of "some" type (B class cannot be
    // accessed) and can even do something with it!
    auto b = Outer.getInner();
    writeln(b); // 30
}

Same program in C# (private members are accessible only within their class):

using System;

public class Program {
    class Outer {
        private class Inner {
            private int field = 30;
            public override string ToString() => field.ToString();
        }
        // Error: Inconsistent accessibility: return type 'Program.Outer.Inner'
        // is less accessible than method 'Program.Outer.getInner()'
        public static Inner getInner() {
            return new Inner();
        }
    }
	
    public static void Main() {
        var b = Outer.getInner();
        Console.WriteLine(b);
    }
}
June 16, 2023

And since classes can be declared locally inside methods, you can also do something similar this way:

import std.stdio;
import std.conv;

Object getB() {
    class B {
		private int field = 30;
        override string toString() => to!string(field);
	}
    return cast(Object)new B();
}

void main() {
    auto b = getB();
    writeln(b); // 30
}
June 16, 2023
Yes that is to be expected.

Also we have a Discord server which you are welcome to join!

https://discord.gg/bMZk9Q4
June 16, 2023

On Friday, 16 June 2023 at 07:54:21 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

Also we have a Discord server which you are welcome to join!

https://discord.gg/bMZk9Q4

Thanks for the invitation. However, I don't like Discord so I don't use it :)

June 16, 2023

On Friday, 16 June 2023 at 07:47:50 UTC, Murloc wrote:

>

And since classes can be declared locally inside methods, you can also do something similar this way:

import std.stdio;
import std.conv;

Object getB() {
    class B {
		private int field = 30;
        override string toString() => to!string(field);
	}
    return cast(Object)new B();
}

void main() {
    auto b = getB();
    writeln(b); // 30
}

This isn't fully playing to its strengths either, there's no need to cast it to Object if you declare the return type to be auto.

import std.stdio;
import std.conv;

auto getB() {
    class B {
        private int field = 30;
        override string toString() => to!string(field);
    }
    return new B();
}

void main() {
    auto b = getB();
    writeln(b); // 30
}

I use it a lot like so:

import std;

auto getThing()
{
    struct Thing
    {
        int x, y;
        double weight;
        int fluffiness;
    }

    Thing thing;
    thing.x = 42;
    thing.y = 128;
    thing.weight = 99.9;
    thing.fluffiness = 9001;
    return thing;
}

void main()
{
    //Thing thing;  // Unidentified identifier Thing
    auto thing = getThing();
    writeln(typeof(thing).stringof);  // Thing
    writeln(thing);  // Thing(42, 128, 99.9, 9001)
}

https://wiki.dlang.org/Voldemort_types