2

I have a C# project with a static class MyNamespace.Global. It contains things like constants that are used throughout the code. e.g. Global.MAX_NAME_LENGTH. One of the 3rd party nuget packages I'm using declares a class Global without a namespace. When I try to build my project, I get a bunch of errors saying Global does not contain MAX_NAME_LENGTH. It's trying to use the 3rd party Global class instead of my class, even though I have "using MyNamespace" at the top of my source files. Is there a way to get around this without changing all of my calls to MyNamespace.Global or renaming my Global class?

3
  • 1
    Why is renaming your Global class an issue? You can use the "rename" tool, that will properly rename all relevant references. (note: do it from a code version where it compiles properly) Commented Oct 11, 2024 at 13:42
  • 1
    Probably not what you wanted to hear, but I would strongly recommend renaming your class ASAP. Naming things with well-known identifiers is already a bad practice in and of itself (see the global specifier). The fact that a library you consume also did it is terrible, but shouldn't preclude you from avoiding the bad practice in your own code. I won't even go into the bad practice of having global variables in the first place... if you really want those, fair enough, just rename the class to something else or something more specific. Pursuing other solutions is a waste of time IMHO. Commented Oct 11, 2024 at 13:42
  • 1
    You could alias your class in the using and then call it by its alias using CorrectGlobal = MyNamespace.Global; and then use CorrectGlobal.MAX_NAME_LENGTHin code. Commented Oct 11, 2024 at 14:05

2 Answers 2

2

The easiest way I'm aware of to avoid this problem and make sure you always consume your class which is inside of your own namespace is to move your using directives to inside your namespace declaration.

If you have this:

using YourNamespaceWhereYourGlobalIs;

namespace SomeOtherNamespaceYouOwn;

internal class Consumer
{
    public void M()
    {
        Console.WriteLine(Global.Y);
    }
}

It will attempt to use the global-scoped Global class. But if you move the using inside, like this:

namespace SomeOtherNamespaceYouOwn;

using YourNamespaceWhereYourGlobalIs;

internal class Consumer
{
    public void M()
    {
        Console.WriteLine(Global.Y);
    }
}

It will now default to using the Global class inside of the YourNamespaceWhereYourGlobalIs namespace.

Couple of notes on this:

  1. Using declarations inside of the namespace like this are actually a good standard, and encouraged by StyleCop. It is not the default setting in Visual Studio, however
  2. I'd still rename your Global class regardless since that's a very poor name for a class (or even a namespace) because global is an existing reserved keyword in the language and one should avoid reusing those.
Sign up to request clarification or add additional context in comments.

Comments

1

To disambiguate between two like-names types (fully qualified names) in two packages, you need "external alias". First, in your package reference, add an alias to one of the packages, for example Aliases="foo" as an attribute on the <Package reference...>. Now add extern alias foo; in an individual C# file to tell the compiler to include that alias, but that isn't enough by itself; now you can use foo::Global.Whatever to explicitly mean that type.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.