CS0436 compiler warning with a shared project - c#

We have two solutions (C#, VS2015) that consist of a few projects.
The Basic-Solution with namespace Wpf has some classes that are re-written in the More Advanced - Solution in the namespace Wpf.Advanced because the more advanced solution uses different data types for example.
Since every code-change in one of the classes, that are present in both solutions, needs to be rewritten in the second file, we decided to change the structure and use a shared project as a single place where the files should be located for both solutions.
We now use "usings" in combination with precompiler #if #else #endif blocks to merge the two files into one by changing the data types based on the project (via a compilation symbol ADVANCED).
Now to the problem:
Since some of our example projects need to reference both, the Wpf and the shared project we get the mentioned warnings CS0436 because some objects, that now exist in the shared project and in the namespace Wpf.
How can I resolve this issue?
I mean, everything works, but no warning is better than any warning, thank you!

I just had similar situation. In exe project I referenced dll and shared project. The dll in turn was referencing shared project. The solution was to exclude the shared project from the exe project. Since the shared project gets referenced from the dll the exe gets all of them too.
It may look trivial unless you are not experienced with shared projects.

The namespace NamespaceName1 in NamespaceName2 conflicts with the type TypeName1 in NamespaceName3
This error occurs when the imported type and the imported namespace have the same fully qualified name. When that duplicate name is referenced, the compiler is unable to distinguish between the two.

Related

Referenced DLLs with shared classes

Here's the issue I'm running into.
Project #1 - DLL
- Includes SomeCommonFile.cs file with several classes
Project #2 - Different DLL
- Includes SomeCommonFile.cs file with several classes
Project #3 - A web service
- Includes SomeCommonFile.cs file with several classes
- Includes references to both the DLL files.
So I've got the DLLs imported in just fine in Project #3, after putting aliases on the references, and "extern alias" at the top of the relevant code files.
But here's the problem when coding in Project #3: every single class in that SomeCommonFile.cs has three versions - one for each dll, and one in Project #3. Is there any easy way to structure this so that I don't have to have conversion functions all over the place (converting Project1DLL.CommonClasses.MyClass to WebService.CommonClasses.MyClass, etc)? At this point, I'm at the point where I'm going to Link Projects #1 and #2's code files instead of their DLL, just to simplify the classes, even though that sounds bad from a maintenance perspective.
The solution is to not include the common classes in each of three different projects in your solution.
If both of your DLLs need to reference some common code, and neither can reference the other, then have a 4th DLL with the common code that they both (along with the web project) reference.
Now you only have one copy of the classes, and they all play nice with each other.

CS0436: Type conflicts with the imported type

I am including an instance of the same source files in multiple assemblies using the Add As Link option. I specifically need to include an instance of the same source within these assemblies because it is responsible for licence validation which must occur internally to the assembly. Performing licence calls across module boundaries could introduce a security risk.
Some of the projects in my solution that include the code depend on other modules that also include it, resulting in warning CS0436:
"The type [type] in [licence.cs full path] conflicts with the imported
type [LicenceClass] in [dependency project also including licence.cs].
Using the type defined in [licence.cs full path]".
I have tried declaring a class alias, but the definitions internal to licence.cs cause the same warning. In the alias, there must be a reference to the duplicated class name which causes the same warning.
I know it is bad practice to duplicate source between assemblies, but it is intentional in this case. I would rather keep a central instance that each assembly links to rather than a dedicated instance with renamed classes to avoid the warnings.
The workaround I have is simply to ignore the warning using a #pragma. Is there a more elegant solution?
It is worth noting that another way to get such warnings is by simply setting a project in visual studio to reference itself: References -> Solution -> etc etc (how I figured this gem out is left as an exercise to the reader ...)
Visual Studio will happily comply, only to throw a wall of warnings of the type described by OP during build, which is to be expected (upon reflection) since every single class etc is getting defined twice.
The only time conflicts occur is when two dependent classes include the same class. There are two workarounds:
Disable the warning in classes that cause CS0436:
#pragma warning disable 0436
Have a separate instance of the class, uniquely named in each client project (undesirable from a maintenance point of view).
EDIT: There is also a solution: do what Mark suggests below, and mark duplicate classes internal.
I had a web application I converted from ASP.NET 3.5 to 4.5 when I moved to VS2015. I started seeing this as a warning, but the solution would still compile. There were no circular references, and cleaning the solution and deleting the bin and obj folders didn't help.
It turns out that VS2015 wasn't happy with some of my classes in the App_Code folder. The classes in here had the same namespace as the rest of the web pages in the parent folder. Once I moved these classes out of the App_Code folder and to the top level of the web application, the warnings went away.
In .NET Core you can also disable the warning in project.json:
{
"buildOptions":
{
"nowarn":
[
"CS0436"
]
}
}
I had this error but not with 2 different classes!
Each new class where in conflict with itself, so obviously I had that CS0436 Error.
After some struggling found out that it was about Mirror Asset that I was using in my multiplayer Unity project. Mirror somehow was including every new class that I make (and inherit from NetworkBehavior).
My external editor was VSCode (visual studio code, solution might also apply to visual studio).
Solution
in
Edit / Preferences / External tools / "Generate .csproj files for:"
I started testing different settings, and this worked for me:
(Not sure if the exact settings work for all, but not having the right files in project, leads to this error. like my case.)
Click Regenerate project files and restart Unity and VSCode after applying these settings (or the setting that suits your project).
I've met such a case when removed some source files temporarily and restored them back later. It happens that IDE (Rider in my case) tries to restore the classes so when they were missing it just added the reference to the resulting exe. Evidently, when I restored the files, they look as duplicate.
The reference IDE inserted looks like this and it's enough to just remove it to fix:
<Reference Include="AppName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>bin\x86\Debug\AppName.exe</HintPath>
</Reference>

Creating a dll containing many namespaces

Suppose I have a bunch of namespaces:
SuperNamespace.namespace1
SuperNamespace.namespace2
SuperNamespace.namespace3
SuperNamespace.namespace4
...
SuperNamespace.namespaceN
Each namespace has its own project and each project creates its own dll file:
SuperNamespace.namespace1.dll
SuperNamespace.namespace2.dll
SuperNamespace.namespace3.dll
SuperNamespace.namespace4.dll
...
SuperNamespace.namespaceN.dll
I like this design because it allows developers to use only the code that they need. Sometimes having a bunch of dll's can be a bit cumbersome and annoying. I would like to create a SuperNamespace.dll which contains all of the namespaces. That way, a developer has the option to use what he/she needs or just take the big dll file, i.e. SuperNamespace.dll containing all libraries:
SuperNamespace.namespace1
SuperNamespace.namespace2
SuperNamespace.namespace3
SuperNamespace.namespace4
...
SuperNamespace.namespaceN
Is there a way to do this in a C# Visual Studio 2010 solution?
I would simply create one large project with all sources unless there are other reasons to keep separate assemblies.
In later case I'd still create one project that includes everythin in addition to small projects before going ILMerge route as Mith Wheat suggested. You can easily create new project from a lot of files using File->New project from source (may need higher version of Visual Studio for that, defintely not Express ones).
There is no restrictions how many C# namespaces can be used in in one assembly (DLL). You can find many examples in .Net framework itself - i.e. many of System.* namespaces come from the same assembly.
Opposite is true also - same namespace can come from multiple assemblies.
Note that in compiled code there is no such thing as "namespace" - it becomes part of class/struct/enum name.

How To Include Classes From Another Namespace In Assembly Instead of Writing Them Into A Separate DLL File?

I have a C# project with two namespaces. A GUI (Stoff3GUI as namespace) with the GUI xaml and .cs files, marked as starting object and a Library (Stoff3Lib as namespace) with all the classes doing the actual work.
Now, when I compile my code, I will receive a .exe file Stoff3GUI.exe and a .dll Stoff3Lib.dll. In Visual Studio, both namespaces are part of the same Project.
How can I compile the classes from the Stoff3Lib into the .exe file without producing a separated .dll file?
Edit:
Changed the xxx to my project name Stoff3 for better understanding.
If both namespaces are part of the same project, you should already only end up getting a single assembly.
This can differ with web project setups (various different flavours of web projects create assemblies in times and manners I've never understood) but for standalone executable projects, it really is "one project produces one assembly" in all cases as far as I'm aware. Double-check that you really only have one project - for example, you shouldn't have any references in the project to an xxxLib assembly.
I'm not entirely sure what you are doing here. It sounds like you might have a single 'Solution' with two projects My immediate thought is just to move the classes you want into the the GUI start project and delete the other project.
I believe what you really have is 1 Visual Studio solution with 2 projects.
Since a picture is worth 1000 words, and just to clear up terminology, here's what that looks like in VS2012:
The output of this solution is exactly what you describe:
TwoProjects\Stoff3GUI\bin\Debug\Stoff3GUI.exe
TwoProjects\Stoff3Lib\bin\Debug\Stoff3Lib.dll
The easiest way to accomplish what you want is to have a single VS project that contains 2 different namespaces. It's good practice to add folders that match your intended namespace structure, in your case Stoff3GUI and Stoff3Lib:
When you compile this solution, the output will be a single EXE, but you still maintain the separation of model and view namespaces very clearly in your folder/file structure:
OneProject\bin\Debug\OneProject.exe

How to override VS2010's automatic folder->namespace mapping in new cs files

Projects are often broken down into folders, and those folders are typically expected to map to code namespaces. However, in many of my core projects I have classes that I have merged into existing namespaces - for example I have an MVC reference library that adds additional types into System.Web.Mvc, or System.ComponentModel.DataAnnotations, for example.
In other projects, I might have a suite of interfaces and a suite of default implementations of those interfaces; so I might split the code files into two separate folders (e.g. 'Objects' and 'Interfaces') but I don't want to have Objects and Interfaces sub namespaces.
Equally, I often write extension methods for types in other libraries - e.g. System.String, which I merge into the System namespace so they are already 'there' as soon as you reference the assembly.
So given a project structure like this (in response to the first answer, this project is intended to produce a single assembly with all the namespaces; and could be a dll that might be signed):
Our.Core.Library
|->System
| |->StringExtensions.cs
|->System.Web.Mvc
| |->AnotherModelBinder.cs
|->OurCoreClass.cs
In the above, I want new files added to the root to be in the namespace Our.Core.Library, but I want new files added to the System and System.Web.Mvc folders to be in System and System.Web.Mvc respectively. But VS will give them a default namespace of Our.Core.Library.System.
It's a small gripe, but I'd like to be able to override the default namespace for a specific code folder so I can control it. Any ideas how to achieve this? I've tried an empty default namespace for the project, which might logically make it work for sub-folders, but obviously not for the root; however, the VS Properties page doesn't accept an empty namespace.
Ideally it would be a solution that I can easily replicate across our entire dev team to enable other developers to be able to add code files whilst adhering to the namespace structure set out at the architect/planning stage.
Every C# project settings has a Default namespace option in the application tab that you can change to any other value which will take effect when you add more files to the project. There is only one setting allowed per project
You can break your project into multiple projects and have the default be different for different projects
Basically the only way I'm going to be able to do this is to write my own extension to Visual Studio. It might even require it's own project or item wizard - if I can get anything working I'll post it up here in the future.

Categories