Beef icon indicating copy to clipboard operation
Beef copied to clipboard

Nested namespace inconsistency

Open Grimelios opened this issue 1 year ago • 0 comments

Consider the following example. As the comments describe, attempting to declare a field of type B.BStruct fails (Type could not be found), but the local variable b compiles successfully.

namespace A
{
    namespace B
    {
        public struct BStruct
        {
        }
    }

    public struct AStruct
    {
        // This works!
        public A.B.BStruct bStructWithSurroundingNamespace;

        // This doesn't work!
        public B.BStruct bStructWithoutSurroundingNamespace;

        public void Func()
        {
            // ...but this *does* work!
            let b = B.BStruct();
        }
    }
}

Here's a slightly modified example with a Main function. This program compiles and runs successfully, printing 123 to the console.

namespace A
{
    namespace B
    {
        public struct BStruct
        {
            public int myInt;

            public this()
            {
                this.myInt = 123;
            }
        }
    }

    static
    {
        public static void Main()
        {
            let b = B.BStruct();
            let buffer = new String();

            Console.WriteLine(b.myInt);
            Console.ReadLine(buffer);

            delete buffer;
        }
    }
}

Here's where things get weird. I've isolated the Main function below. First, changing the b declaration to include the scope keyword fails compilation:

public static void Main()
{
    // Note the scope keyword that was previously absent.
    let b = scope B.BStruct();
    let buffer = new String();

    Console.WriteLine(b.myInt);
    Console.ReadLine(buffer);

    delete buffer;
}

Compilation also fails when declaring b's type explicitly:

public static void Main()
{
    // In this case, adding the scope keyword changes nothing, i.e. compilation still fails.
    B.BStruct b = .();
    let buffer = new String();

    Console.WriteLine(b.myInt);
    Console.ReadLine(buffer);

    delete buffer;
}

Given these examples, it's clear that, under the current implementation, the second example (the one with a Main function that runs successfully) is the odd man out.

Additional context: I stumbled onto this scenario when attempting to declare B.BStruct inside a function within namespace A. My assumption was that, within a particular namespace, I could implicitly access child namespace. In other words, inside Main (which lives inside namespace A), I would expect let b = scope B.BStruct(); to work, since namespace B is conceptually a "sibling" of the function.

To verify my expectation, I wrote a quick C# program, shown below. This function compiles and runs successfully.

namespace A
{
    namespace B
    {
        public struct BStruct
        {
            public int myInt;

            public BStruct()
            {
                myInt = 123;
            }
        }
    }

    public static class Program
    {
        public static void Main()
        {
            // This works!
            var b = new B.BStruct();

            Console.WriteLine(b.myInt);
            Console.ReadLine();
        }
    }
}

Grimelios avatar Jul 17 '24 14:07 Grimelios