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(

Azure AD and AWS Cognito side-by-side

In the last few weeks, I was involved in multiple opportunities on Microsoft Azure and Amazon, where we had to analyse AWS Cognito, Azure AD and other solutions that are available on the market. I decided to consolidate in one post all features and differences that I identified for both of them that we should need to take into account. Take into account that Azure AD is an identity and access management services well integrated with Microsoft stack. In comparison, AWS Cognito is just a user sign-up, sign-in and access control and nothing more. The focus is not on the main features, is more on small things that can make a difference when you want to decide where we want to store and manage our users.  This information might be useful in the future when we need to decide where we want to keep and manage our users.  Feature Azure AD (B2C, B2C) AWS Cognito Access token lifetime Default 1h – the value is configurable 1h – cannot be modified

What to do when you hit the throughput limits of Azure Storage (Blobs)

In this post we will talk about how we can detect when we hit a throughput limit of Azure Storage and what we can do in that moment. Context If we take a look on Scalability Targets of Azure Storage ( https://azure.microsoft.com/en-us/documentation/articles/storage-scalability-targets/ ) we will observe that the limits are prety high. But, based on our business logic we can end up at this limits. If you create a system that is hitted by a high number of device, you can hit easily the total number of requests rate that can be done on a Storage Account. This limits on Azure is 20.000 IOPS (entities or messages per second) where (and this is very important) the size of the request is 1KB. Normally, if you make a load tests where 20.000 clients will hit different blobs storages from the same Azure Storage Account, this limits can be reached. How we can detect this problem? From client, we can detect that this limits was reached based on the HTTP error code that is returned by HTTP