We have two applications that each compile their own code with some of the code being shared (mainly data related). It felt natural to split this design up into three namespaces and try to enforce that namespace Foo never imports namespace Bar but either can import namespace Shared.
I hope Venn diagrams are appreciated as a visualization:
However one of the classes between Foo and Bar slipped through the cracks and someone referenced a class from Bar inside Foo despite the enforcement.
And that got me wondering if how the C# compiler actually deals with this? The way I see it, one of two things could happen.
The entire namespace gets compiled into Foo. Leaving the diagram to look like this:
Or the compiler is smart enough just to extract the necesarry class. Making the diagram look like this:
I can't seem to find any documentation on how usings and namespaces compile. It seems like namespaces are just to organise code for developers, not compilers. Yet they provide scope... So I guess #2 applies then? How to even test this?
There is no correspondence between namespaces and assemblies: one assembly may contain many namespaces, and one namespace may span many assemblies.
The compiled IL code in an assembly refers to types by their fully qualified names: Foo.SomeClass instead of SomeClass, Bar.OtherClass instead of OtherClass, and so on. The compiler's job is to figure out which fully qualified type name you really mean when you write the shortened form SomeClass -- because you could have defined a class called SomeClass in the namespaces Foo, Bar, or even System!
When you write:
namespace Foo
{
public class SomeClass
{
}
}
You are defining a type with a fully qualified name Foo.SomeClass.
When you write:
using Foo;
...
SomeClass instance = new SomeClass();
The compiler treats this the same as:
Foo.SomeClass instance = new Foo.SomeClass();
Namespaces are just a construct of convenience for organizing these fully qualified names. When you say using Foo;, you are just telling the compiler to search for fully qualified names that start with Foo. whenever you type SomeClass. There is nothing being "imported" when you write using Foo;, it just provides a convenient alternative to writing Foo.SomeClass everywhere; nor does any "code" (in the sense of IL instructions being emitted) get generated by your usings or your namespaces. All it does is tell the compiler to put Foo.SomeClass into the IL whenever you write SomeClass.
The above is a simplification of a more nuanced set of rules defined in the spec for resolving short-form type names; you can read this for more details: here and here
The level at which you'd want to enforce the dependencies in your diagrams would be at the assembly reference level: if the Foo project never references the Bar assembly or vice versa, the code would not even compile if you tried to reference a type in one assembly from the other. The namespaces don't really have much to do with that at all, because again, nothing stops you from defining types in the Foo namespace but in the Bar assembly.
Related
I know C# supports namespace nestings, as does C++, which both allow code that looks like this...
namespace A {
namespace B {
...
}
}
Coming from a C++ background and diving into the C# world I've been meditating upon what appears as a hierarchical nesting of components via all the using directives that must be issued to exploit .NET, eg
using System.Collections;
using System.Collections.Generic;
I'm sure Microsoft intended and designed these libraries to be logically hierarchically organized, but without the aid of seeing the source I cannot verify if System.Collections.Generic has Generic as a nested namespace of Collections, but I assume it is, and that it was accomplished with namespace nestings like seen with A and B. Now once I start cooking up things in my own source and declaring code that looks like this
namespace C.D {
...
}
what exactly am I achieving here with respect to a hierarchy? Am I introducing to the code a singular namespace identifier "C.D" where the '.' is simply a friendly means of suggesting a hierarchy that may or may not exist depending upon the code structure or am I implicitly declaring two namespaces "C" and "D" with D nested within C? I've come across this question while cooking up a DevelopmentApplications namespace to our C# codebase that is meant to strictly contain all development tools used to augment our software to aid in its development. In those tools I've never declared a standalone enclosing namespace DevelopmentApplications (which is something I would HAVE to do in C++)...
namespace DevelopmentApplications
{
...
}
...but instead always create applications that go like
namespace DevelopmentApplications.MyDevelopmentApp
{
...
}
I know this area is a cause of confusion for some because of the following question where the author is struggling to understand the relationship between Foo.Bar.Baz and Foo.Bar. There's also an inverse question of a C# developer entering C++ land that gives some insight into this issue.
I suppose another way to state the question is that in C++ using the '::' operator to fully qualify a type I know guarantees that the code that type was declared in is nested deep in some namespace hierarchy. But in C# using the '.' operator to fully qualify some type must that type also exist in some deeply nested namespace hierarchy? I'm assuming here that C#'s use of a namespace like A.B.C does not necessarily require a hierarchical relationship between A B and C or that A B or C even exist as individual namespaces.
If someone can find or knows the relevant language specification regarding this syntax I'd love to read it.
Section 9.2 of the C# 4.0 specs states:
The qualified-identifier of a namespace-declaration may be a
single identifier or a sequence of identifiers separated by “.”
tokens. The latter form permits a program to define a nested namespace
without lexically nesting several namespace declarations. For example,
namespace N1.N2
{
class A {}
class B {}
}
is semantically equivalent to
namespace N1
{
namespace N2
{
class A {}
class B {}
}
}
You state:
I'm assuming here that C#'s use of a namespace like A.B.C does not necessarily require a hierarchical relationship between A B and C or that A B or C even exist as individual namespaces.
That assumption is false. The namespace A.B.C necessarily involves namespace A in the global namespace, namespace B within namespace A, and namespace C in namespace B.
Some facts about namespaces in C#:
They are collective. You can declare a namespace in several different source files, and the compiler will treat them all as the same namespace.
You can nest namespaces inside each other, but it's much more common to simply declare the nested namespace in another source file.
There is a global namespace, accessible to every class as global::
Coming from C++ background myself, it takes some time to get used to C#. In C#, one uses the dot operator (.) more often than the ::-operator (the namespace qualifier operator in C#), to access namespace and class scopes.
In C++, one uses the dot operator (.) to access members of an instance of a class. Scope resolution operator (::) on the other hand, is used to access members of a class without an instance of that class. To me, this makes sense and is both logical and consistent.
While I can accept different approach used in C#, there seems to be at least one instance, in which I see an inconsistence. At least, that is how it appears to me. It has to do with the global keyword:
global::System.Console.WriteLine("Hello World");
Could somebody explain to me why namespace alias qualifier is required to use with global keyword instead of the dot operator?
It's not really common but there are some situations when it's handy.
Imagine you have this a class System inside current namespace:
namespace Test {
static class System {
public static Do() { }
}
class Foo {
void foo() {
System.Do(); // What's this?
}
}
}
Do you want to make it more complicate? Add an inner class in System and call it, for example, Action. Of course these are edge cases and probably you won't ever need to use global:: but language itself has to handle this situation. See MSDN for more examples.
Global namespace aliases are also useful in another situation: when you reference two DLLs and they have the same namespaces and classes (for example because they simply are the two versions of same stuff). In that case how can you reference them? Same problem described here for C++. You can change namespace to include version number but it's a pain each time you change it (and VS automatic refactoring AFAIK doesn't work with namespaces) or you can reference them using two aliases. They'll be accessed, for example, like this:
Version1::CompanyName.MyNamespace.MyClass
Version2::CompanyName.MyNamespace.MyClass
Also note that it's a good practice (to include global:: namespace) when you're generating code (for example all designers generated code) because you don't know in which scenario that code will be compiled (then collisions may occur).
Reasoning about :: and . well...it's not a question for SO (unless you're so lucky Eric is having some fun here on SO) but I may guess it's because they're different things. If same operator . is used then how can parser understand with global.System you want to use global namespace alias and not a class or namespace named global? They had to make global a reserved keyword and it won't solve the other problem of conflicting hierarchies...
I have a solution with two projects. One namespace is MarketplaceWebServiceOrders and the other is MarketsplaceWebServiceOrders.Sample. I have public interface in the MarketplaceWebServiceOrders called MarketplaceWebServiceOrders. My main function is in MarketplaceWebServiceOrders.Sample and whenever I try to use the interface MarketplaceWebServiceOrders I get Error: MarketplaceWebServiceOrders.Samples.MarketplaceWebServiceOrders is namespace used use like a type.
I actually have this program compiled and running but I need to make changes and this popped up.
In this case you can access your interface specifying full name with namespace:
MarketplaceWebServiceOrders.MarketplaceWebServiceOrders instance = new ...();
Anyway, your naming looks wrong. You are probably misusing namespaces - they should "categorize" types, no need to have type name the same as namespace. Moreover, interfaces are prefixed with I letter by good convention.
You may want to consider refactoring your code to make the namespace and types a little less ambiguous. One of the purposes of namespaces is to organize code, so it's a bit redundant to have the same name in both the namespace and the type.
Well, the error states that you have an additional namespace level MarketplaceWebServiceOrders in the MarketplaceWebServiceOrders.Sample namespace. Is this true? If so, you will need to fully qualify the usage of the interface from the base namespace: MarketplaceWebServiceOrders.MarketplaceWebServiceOrders is the interface you say you want. Just don't use the base MarketplaceWebServiceOrders namespace in this code file.
To avoid this confusion if at all possible I would change the namespace name or the interface. The interface would be easier; add an "I" to the front of the identifier if it is an actual C# interface type (it's recommended naming convention in most C-style languages).
I got a strange error when tried to build my project ExpertSystem in solution ExpertSystem:
Error 1 The type name 'App' does not
exist in the type
'ExpertSystem.ExpertSystem' D:\Users\Kirill\Documents\Visual
Studio
2010\Projects\ExpertSystem\ExpertSystem\obj\x86\Debug\App.g.cs 60 26 ExpertSystem
I didn't even knew that VS creates this file while building. So, I started search the problem in my last edits in code and found that problem is in my last class:
namespace ExpertSystem
{
public class ExpertSystem
{
//...
}
}
When name of class is changed to something different from ExpertSystem, project compiles without errors.
Can anyone explain, can I actually have classes in C# with the same name as namespace/project/solution? Or is this a some kind of VS/WPF bug?
Thanks.
VS generates partial class for each XAML file (not during build, but during design), in order (for instance) to declare and fill the named components as class fields.
If you want to easily read the content of the designer generated App.g.css file (associated with the App.xaml and App.xaml.cs file), go to the App.xaml.cs file and perform a "Go to Definition" on the InitializeComponent() function call in the class constructor. I don't know what lurks in your, but I would expect that the designer generated something like this (maybe not this, but the issue will be the same):
var foo = (SystemExpert.App)(Application.Current)
Which should be understood as:
var foo = (global::SystemExpert.App)(Application.Current)
Now, if you create a SystemExpert class in your SystemExpert assembly namespace, and as the App class is declared in the SystemExpert namespace too, the compiler will understand that:
var foo = (global::SystemExpert.SystemExpert.App)(Application.Current)
^^^^^^^^^^^^^^^^
the current namespace
Naming a class exactly the same way as a namespace is bad practice: it can confuse the compiler.
Can anyone explain, can I actually have classes in C# with the same name as namespace/project/solution?
Yes, you can. It's part of the C# language.
Therefore the compiler can't figure out whether the code meant to look for the ExpertSystem.ExpertSystem namespace or the ExpertSystem class in the ExpertSystem namespace. (Well it can, but it got it wrong.)
To complement BoltClock's answer with a solution that will work while keeping the namespace and class names as they are:
The error is reported in a file named App.g.cs, which is generated by the compiler. Thus, fixing the issue in that file will not help, as the file will be overwritten with the error upon the next compilation (or rewritten once you have copied the code to another machine).
However, you can change the App.xaml file, from which App.g.cs is generated. The root element of the file will start with something like
<Application x:Class="ExpertSystem.App"
In there, the namespace ExpertSystem is supposed to be found, but with the class having the same name, the compiler assumes that App is a member or a nested type in your class ExpertSystem.ExpertSystem.
By pondering about this, you will realize that the compiler first tries to evaluate the value of the x:Class attribute relatively to the ExpertSystem namespace for some reason. This behaviour is responsible for your problem, but as we now know the specifics of the behaviour, we can write the code accordingly - with an identifier that is qualified relatively to the namespace ExpertSystem:
<Application x:Class="App"
After this change, it should compile fine, even if both the namespace and the class are named ExpertSystem.
Can I expose a class from another .net namespace as a class in my namespace? I use a class - antlr.collections.AST - as the return type for a function belonging to a class in my namespace; as a result, the user has to have
using antlr.collections;
using myNamespace;
at the top of their files in order to use my function. Can I make myNamespace.AST an alias for antlr.collections.AST, such that the user only has to have
using myNamespace;
at the top of their files?
Bear in mind that the consumers of your code won't actually need to have using statements. Those are there to make their lives easier, so they don't have to type antlr.collections.Foo and antlr.collections.Bar all over their source.
The bigger "impact" (if indeed there really is a severe one) is that the consumer of your code will need a hard reference to the assembly where antlr.collections is defined.
However, if that's documented up front, I honestly don't see it being that big of a problem. It's no different than the consumer of a SubSonic-generated DAL needing references both to the generated DAL assembly and the original SubSonic assembly. (And, quite possibly, using statements as well.)
Dependencies are what they are. There's a reason classes are broken into namespaces -- primarily for organization and to reduce naming conflicts. Not knowing what classes are in the namespace you mention, I don't know how likely such a conflict actually is in your scenario ... But attempting to move the class from one namespace to another, or to hide the fact that such is needed by deriving a blank class from it, is probably not the best idea. It won't kill the consumers of your class to have another reference and using statement.
How about deriving a class using the same name in the new namespace? I meant:
namespace MyForms {
class Class1 : Some.Other.Namespace.Class1 {
// ...
}
}
create a new class that inherits the class in your new namespace. It's not ideal, but it's useful for unit testing and the like.
You should think about why you are doing this though, classes are broken up into namespaces for a reason.
No, you can't.
The full path to and name of a class is part of its identity.
If you derive from the class and return your derived class, you'll make yourself responsible for providing all of the documentation for the return type.
I think you'll be doing the developers who use your library a disservice because they won't necessarily know that what they're really working with is a type from antir.collections (not that I even know what that is, but that's not the point). If the developer comes to StackOverflow.com searching for information on that return type, are they more likely to find information if the type is from a "common" library, or from yours?
The only solution is to hide the whole dependency to the type antlr.collections.AST.
You can use an Adapter fot that purpose.