Skip to main content

[Code refactoring] Class name and namespace with the same name (deadly sin)

Looking over some ‘old code’ (3-4 years old) I discovered a class nested under a namespace with the same name. For example we have a class called Foo and the namespace above is also called Foo
App.Foo.Foo
In that moment I told to myself something is not okay and we need to do something to change this. The good part was that this class was in internal class, used by other subcomponents – no public API there. I don’t know how I missed this problem until now.
The fix was very simple, renaming the namespace to a more suitable name.
Let’s see why we shouldn’t have a class and a namespace with the same name.
First of all you will have problem referring the namespace and the class. You will have to use the full namespace for the class or an alias. This can create confusion to developers, especially because they will never know when the class is referring or what the alias is. You can have different standards to name an alias but the scope is not to hack the system.
Namespace are used to group different classes, functionalities and so on. Theoretically you hope to get a code that is more easily to change, understood and maintain. When you and up with a namespace and a class under it with the same name than grouping will not help you. You will have an ambiguous namespace and class for all people that will try to use or understand the code under that namespace or code that use it.
When we have a good groping (based on namespaces) you will end up with a hierarchical namespaces, classes and a design that could be read pretty easily.  When someone will try to look over the hierarchical namespaces, he will end up with App.Foo.Foo and will say WHAT? He will need more time to understand why the class is called in the same why us the namespace. Because of this all the concept of grouping the classes using namespaces to organize and for easy understating will fall apart.
In the end, you will end up with a lot of name collisions. You don’t know what and where you are referring. The code will contain a lot of places where you are referring a class based on the full namespaces.
In conclusion I would like to say:
NEVER AND NEVER NAME A CLASS WITH THE SAME NAME AS NAMESPACE! THIS IS ONE OF DEVELOPERS SIN

Comments

  1. It's certainly a bad practice but I wouldn't go as far as to say that it's a "sin". The C# language offers several ways in which you can work with such an organization by using either the full name up to even the global keyword (i.e.: global::MyCompany.Foo.Foo) or through the 'using' directive.

    ReplyDelete
    Replies
    1. Usually you we end up with this issues (namespace and class with the same name) because of lack of inspiration - We don't know how to name our namespace or class correctly.
      In general we have a lot of options, a lot of names that we can use. Yes, there are different ways for workarounds (global, allies), but you don't resolve the real problem - why we ended up in this way.
      Until now I don't remember to find a .NET Core library with this problem. For code that is automatically generated, there we cannot do anything, this is it.

      Delete
    2. Yes Andrei, you can work around this problem, but just because "you can", it doesn't mean that "you should".

      Delete
  2. I think this is more of a limitation of the IDE rather than anything else. Namespaces are not a real part of the language, you can't really do much with the namespace; and the IDE should help rather than go in your way when you use the same namespace and name.

    Thing is, I tend to move to a namespace of its own when a class starts to grow too much; it makes sense that the namespace should have the same name with the class; then I will refactor things into place; but even then, I might have a core implementation named as the namespace.

    X.Foo.Foo happens naturally during refactorings. I don't find it a sin at all.

    ReplyDelete
    Replies
    1. A namespace with a single class inside it's a bit weird.. (if it's not still under development and more classes are going to be added to that namespace).
      Anyway, classes with the same name as the namespace can indeed happen accidentally when grouping several classes together, like:
      [Company].[Product].ShoppingCart.ShoppingCart :)
      when there are many other related classes in the ShoppingCart namespace..

      Delete
    2. @Tudor, in your example, if your namespace is ShoppingCart, than you can rename your class from ShoppingCart to Cart. You are already under a namespace that contains classes related to ShoppingCart.

      Delete
  3. Indeed, at least pluralization in the namespace could save the day: System.Windows.Forms.Form :-)

    ReplyDelete

Post a Comment

Popular posts from this blog

Windows Docker Containers can make WIN32 API calls, use COM and ASP.NET WebForms

After the last post , I received two interesting questions related to Docker and Windows. People were interested if we do Win32 API calls from a Docker container and if there is support for COM. WIN32 Support To test calls to WIN32 API, let’s try to populate SYSTEM_INFO class. [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; } ... [DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI); ... SYSTEM_INFO pSI = new SYSTEM_INFO(

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine: threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration: TeamCity .NET 4.51 EF 6.0.2 VS2013 It see

Navigating Cloud Strategy after Azure Central US Region Outage

 Looking back, July 19, 2024, was challenging for customers using Microsoft Azure or Windows machines. Two major outages affected customers using CrowdStrike Falcon or Microsoft Azure computation resources in the Central US. These two outages affected many people and put many businesses on pause for a few hours or even days. The overlap of these two issues was a nightmare for travellers. In addition to blue screens in the airport terminals, they could not get additional information from the airport website, airline personnel, or the support line because they were affected by the outage in the Central US region or the CrowdStrike outage.   But what happened in reality? A faulty CrowdStrike update affected Windows computers globally, from airports and healthcare to small businesses, affecting over 8.5m computers. Even if the Falson Sensor software defect was identified and a fix deployed shortly after, the recovery took longer. In parallel with CrowdStrike, Microsoft provided a too