C# namespaces: how to follow standards without causing annoying conflicts?

227 views Asked by At

I'm working on a C# library (let's just call it "Foo" for the sake of this question). It has some needs very similar to standard .NET needs: for example, it provides some drawing services, and some conversion services.

For the sake of familiarity and users of the library being able to guess what things are called, I'd like to follow the .NET standard, and name these parts of the library Foo.Drawing and Foo.Convert (and so on). But I'm finding that in actual use, this causes pain. People almost always have "using System;" at the top of each file, and when using this library, they want to have "using Foo;" as well. But now they have two Drawing and two Convert modules, and hilarity ensues.

For example, now instead of just using Drawing.Color for a parameter or variable type, you have to explicitly spell out System.Drawing.Color, or the compiler complains that Foo.Drawing doesn't have a Color type. Similarly, you want to use a standard Convert.ToInt32, you have to say System.Convert.ToInt32, even though you're already using System, because otherwise it finds Foo.Convert and fails to find ToInt32.

I understand why all this is as it is, but I'm still new to the C# community, so I don't know which is the most standard solution:

  1. Leave it this way, and expect users to use fully-qualified names where necessary?
  2. Rename the conflicting modules to something else (maybe Foo.Graphics instead of Foo.Drawing, and Foo.Conversion instead of Foo.Convert)?
  3. Use some prefix on the standard names (Foo.FDrawing and Foo.FConvert)?
  4. Something else?

Any advice from you more experienced C# gurus will be appreciated!

2

There are 2 answers

0
Xiaoy312 On

You can use namespace aliasing :

using System;
using FConvert = Foo.Convert;

public class Bar
{
     public void Test()
     {
          var a = Convert.ToInt32("1");
          var b = FConvert.ToInt32("1");
     }
}
1
quantdev On

One of the main usage of namespaces is to avoid name clashing.

It means that namespaces allow developers to create types with identical names, as long as the belong to different namespaces.

A library usually have at least a root namespace, and possibly nested namespaces that logically groups the related types.

Name your types as you wish, as long as the names are meaningful and represent what the type really are. A client of your library expects a type named Animal to represent an Animal, not something else. The same applies for naming namespaces.

However, avoid at all cost the names from System, since it will be really annoying for your library clients (as you described) to deal with conflicting names all over the place.

A common way to deal with conflicting namesapces inside a class is to use namespace aliasing:

 using FooConvert = Foo.Convert;
 using BarConvert = Bar.Convert;