Skip to main content

How to Resolve Error "The type 'Name' in 'ModuleA' conflicts with the namespace 'Name' in 'ModuleB'" in C#

The Compiler Error CS0438 is a Naming Collision error that stops the build. The message reads: "The type 'Name' in 'ModuleA' conflicts with the namespace 'Name' in 'ModuleB'".

This error occurs when your project references two different sources (assemblies or modules), and they both define the exact same identifier at the root level, but they define different constructs:

  1. Source A defines a Type (Class, Struct, Enum).
  2. Source B defines a Namespace.

Unlike Warning CS0437 (where the compiler guesses and picks the Type), CS0438 is a hard error. The compiler refuses to guess because the ambiguity makes the code unresolvable.

This guide explains how to fix this using Extern Aliases to distinguish between the two sources.

Understanding the Conflict

In C#, identifiers in the global namespace must be unique so the compiler can resolve them.

  • Library A: Contains public class Monitor { ... }
  • Library B: Contains namespace Monitor { public class Display { ... } }

If you reference both libraries, the name Monitor is now claimed by both a Class and a Namespace.

  • If you write new Monitor(), you clearly mean the Class.
  • If you write Monitor.Display, you clearly mean the Namespace.
  • However, the compiler builds a symbol table before analyzing usage. It sees two definitions for Monitor and cannot merge a Class and a Namespace into one symbol. Thus, it raises CS0438.

Scenario: The Type vs. Namespace Collision

Imagine you are using two third-party dependencies: Hardware.Core.dll and Hardware.Monitor.dll.

Code in Hardware.Core.dll:

// Defines a root-level Class
public class Hardware
{
public void Initialize() { }
}

Code in Hardware.Monitor.dll:

// Defines a root-level Namespace
namespace Hardware.Monitors
{
public class Screen { }
}

Your Consumer Project:

public class Program
{
static void Main()
{
// ⛔️ Error CS0438: The type 'Hardware' in 'Hardware.Core.dll'
// conflicts with the namespace 'Hardware' in 'Hardware.Monitor.dll'.

// The compiler cannot resolve what 'Hardware' refers to here.
var hw = new Hardware();
}
}

Solution 1: Use extern alias (The Robust Fix)

Since you cannot change the code inside third-party DLLs, the only way to resolve this is to partition the referencing assemblies into different root namespaces using Extern Aliases. This prevents them from colliding in the global namespace.

Step 1: Assign Aliases in .csproj

Open your project file (.csproj) and add an <Aliases> tag to the references. You can alias one or both.

<ItemGroup>
<Reference Include="Hardware.Core">
<HintPath>libs\Hardware.Core.dll</HintPath>
<!-- Give the DLL containing the CLASS a unique alias -->
<Aliases>CoreLib</Aliases>
</Reference>

<Reference Include="Hardware.Monitor">
<HintPath>libs\Hardware.Monitor.dll</HintPath>
<!-- Keep this one global, or alias it too -->
<Aliases>global</Aliases>
</Reference>
</ItemGroup>

Step 2: Use the Namespace Alias Qualifier (::)

In your C# code, explicitly reference the alias to tell the compiler exactly which assembly to look in.

// 1. Declare the alias
extern alias CoreLib;

public class Program
{
static void Main()
{
// ✅ Correct: Access the Class via the specific alias
// 'CoreLib::Hardware' points directly to the class in the aliased DLL.
var hw = new CoreLib::Hardware();
hw.Initialize();

// ✅ Correct: Access the Namespace via the default global scope
// (Since we didn't alias Hardware.Monitor.dll away from global)
var screen = new Hardware.Monitors.Screen();
}
}

Solution 2: Renaming (If you own the code)

If you are the author of one of the libraries, you should follow the .NET Framework Design Guidelines, which state: Do not name a class the same name as a namespace.

Solution: rename the root class or nest it inside a namespace to avoid polluting the global scope.

Refactoring Hardware.Core.dll:

namespace HardwareSystem // Wrap inside a namespace
{
public class Hardware
{
public void Initialize() { }
}
}

Now, in the consumer project:

  • Hardware refers to the Namespace (from Hardware.Monitor.dll).
  • HardwareSystem.Hardware refers to the Class. The conflict is resolved.

Conclusion

CS0438 is a hard stop because the compiler cannot merge a Type and a Namespace with the same name.

  1. Identify the Source: The error message tells you exactly which two files/modules are fighting.
  2. Use Extern Alias: This is the standard solution for third-party library conflicts. It effectively isolates one DLL into its own "folder" (Alias::Name).
  3. Rename: If you control the source, rename the Class or wrap it in a unique Namespace to avoid the collision.