Why I can access class that is defined outside of namespace? - c#

I was wondering Why I can access class when I defined it outside of namespace scope?
I am not very familiar with namespaces, I am just learning, but I thought that namespace should like wrap all my classes to one 'box' and they can access each other just inside that 'box' (scope).
Code example:
class Point
{
public int X;
}
namespace ConsoleApplication12
{
class Program
{
static void Main(string[] args)
{
Point p = new Point();
p.X = 50;
Console.WriteLine(p.X);
Console.ReadLine();
}
}
}
Thank you for answers.

Namespaces have nothing to do with access. It's important to differentiate between namespaces and assemblies - they're often closely related, in that types in a namespace Foo.Bar would be likely to be in assembly Foo.Bar.dll, but that's a convention - it's not something the compiler or language cares about.
A namespace is primarily "a space in which names have to be unique". In other words, while it's fine to have two types called Point in different namespaces, you can't have two types called Point in the same namespace. Indeed, the primary reason for namespaces existing (IMO) is so that we don't all have to use completely unique names across every piece of .NET code in the world.
You can use your Point class which is implicitly internal so long as it's declared within the same assembly. If it's in the global namespace (i.e. not declared in a namespace at all) then you don't need any using directives to refer to it - the purpose of a using directive is to allow you to refer to members of a different namespace just by their short name.
So if you have:
namespace Foo.Bar
{
public class Baz {}
}
then you could access that as either:
namespace Other
{
class Test
{
Foo.Bar.Baz baz = new Foo.Bar.Baz();
}
}
or
// Allow anything in namespace Foo.Bar to be accessed by its
// short name
using Foo.Bar;
namespace Other
{
class Test
{
Baz baz = new Baz();
}
}
If the type is defined in the "global" namespace, then you just don't need the using directive. From the C# 5 language specification section 3.8 (namespace and type names) where it's describing the type name lookup procedure:
If the previous steps were unsuccessful then, for each namespace N, starting with the namespace in which the namespace-or-type-name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located
So in your case, looking for Point from your Main method, first ConsoleApplication12 would be checked for a Point type, then the global namespace.

To access class, outside namespace, your class should be public
public class Point
and in your namespace, where you want to see this class, you need to add namespace in top of usings
using mynamespace.external;
Than you can access your class

Related

C# Namespace question: Must avoid namespace containing any class name overlap?

I'm finding some frustration with the way C# handles namespaces when I want to reference a class whose class name happens to be identical to part of the current class's namespace. This will produce a compiler error, "'Class' is a namespace but is used like a type".
Consider the following code sample, which demonstrates the problem:
namespace A.B.C
{
public class Y
{
}
}
namespace X.Y.Z
{
public class Class1
{
public Y MyProp;
}
}
In this case, I want to use the class "Y" from the namespace "A.B.C". But because "Y" is also one of the parts of the namespace, C# treats "Y" as a namespace, not a type.
I can get around this by fully qualifying the class name, "A.B.C.Y", or using an alias, but my general preference would be for C# not to treat "Y" as a namespace in this context. Often I have code, such as test code, that contains similar namespaces as classes its testing, and this kind of class/namespace collision means having to be a lot more verbose in setting things up.
I'm not sure what the process is called, but it seems that in resolving classes and namespaces, C# will walk up the namespaces until it finds a part of the namespace that matches. In this case, it walks up and finds Y. Is there a way to tell C# not to walk up, not to allow this partial namespace matching?
If you write using A.B.C; (the namespace that Y is in) inside namespace X.Y.Z, the error goes away:
namespace X.Y.Z
{
using A.B.C;
public class Class1
{
public Y MyProp;
}
}

Namespace scope in C#

Does the name of namespace also define the scope in the class?
For example, I have namespace that is named by solution by default. Lets say in Program.cs name of namespace is "MySolution".
in the next file interface that I have created, name of namespace is "Interfaces"
When I go back to class, to implement this interface, it was not in the scope (I could not find it in intellisense). So if class has one namespace, and interface has second namespace, than I cant use it in my class.
I thought namespace is only used to organise classes (like a surname), but I guess it also defines a scope.
"The namespace keyword is used to declare a scope that contains a set of related objects. You can use a namespace to organize code elements and to create globally unique types." https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx
To use a class, interface, struct, enum, delegate from another namespace, you will need to use the fully qualified name of the type, or declare a reference to that namespace with using Interface; at the top of your class. IE:
using Interfaces; //can reference namespaces here
namespace MySolution
{
public class Program
{
//or you can use the fully qualified name of the type
public Program(Interfaces.MyInterface example)
{
}
}
}

Using Multiple Namespaces to Describe a Class

I am writing code for a game, and wanted to include my main method in two different namespaces so that it could easily access all the classes from both the 'Engine' and 'Core' Namespaces.
namespace Engine Core
{
class ExampleClass
{
}
}
Although I just put a space between Engine and Core, I know that this syntax is incorrect, I would like to know how to make a class a member of multiple namespaces. If this is not possible, is there anything that I could do that would act the same? (Classes in neither these two namespaces having to refer to this class by 'Engine.' or 'Core.'
A class can not belong to two different namespaces.
If you want to refer to a class of the Engine or Core namespaces without explicitly writing the namespace each time you reference a type of those namespaces, just use using at the beginning of the file. The using directive allows the use of types in a namespace so that you do not have to qualify the use of a type in that namespace:
using Engine;
or
using Core;
Check the documentation: using Directive
So you want someone to be able to access ExampleClass by using Engine.ExampleClass and Core.ExampleClass? I'm not sure why you would (I'm sure you have your reasons) but two ways to expose something like this are:
namespace Foo
{
abstract class ExampleClass
{
//Only implement the class here
}
}
namespace Engine
{
class ExampleClass : Foo.ExampleClass
{
//Don't implement anything here (other than constructors to call base constructors)
}
}
namespace Core
{
class ExampleClass : Foo.ExampleClass
{
//Don't implement anything here (other than constructors to call base constructors)
}
}
Or you could use namespace aliasing but every cs file using the class would require the alias to be defined.
using Engine = Core;

Quick check regarding C# namespaces

Okay, there's System and System.Web. Am I correct in that the structure this suggests is:
namespace System
{
// all of the outer namespace members
namespace Web
{
// all of the inner members
}
}
And that when a namespace is nested within another, having a using directive with the parent/outer namespace only doesn't automatically bring in the child/nested namespace? In other words:
using System;
public class Example
{
public Example()
{
context1 = new HttpContext(); // won't work
context2 = new System.Web.HttpContext(); // will work
}
}
Just trying to see if I actually understand this correctly.
System.Web is declared as:
namespace System.Web
{
public class HttpContext {}
}
However, it would be possible to actually declare a child namespace:
namespace System
{
namespace Web
{
public class HttpContext {}
}
}
I have never seen something like this but the syntax allows it and the effect is the same. In both cases, the namespace of HttpContext is System.Web.HttpContext.
Even with the second example, using System; wouldn't import the child namespace, only the types defined in that namespace are imported.
You could nest namespaces and any using directive would only grant access to the members defined within the specific namespace you are referencing.
So from your example:
namespace System
{
// all of the outer namespace members
namespace Web
{
// all of the inner members
}
}
Referencing System would grant you access to the outer namespace members and referencing System.Web would grant you access to all of the inner namespace members.
But this is atypical and usually namespaces are defined only once within a file. The dot-notation typically follows a folder or project structure, so files that were nested as such:
WebApplication
- Models
- MyModel.cs
- Controllers
- MyController.cs
Might use namespaces of WebApplication.Models and WebApplication.Controllers.
I can't think of a great example off the top of my head where you would want to nest namespaces, but there may be a good reason to. However, it would be considered an exception to the rule, in my opinion.
Yes, a using directive only allows types declared in that namespace to be used without namespace qualifier. Nested namespaces are not automatically included.
As Daniel said, System.Web is not declared separately. System and System.Web are two separate namespaces which are technically unrelated.
That's why your code example of new HttpContext() won't work - because HttpContext is not in the System namespace at all.
this is a common confusion regarding composite namespaces. Heres a great article of microsoft about it: http://msdn.microsoft.com/en-us/library/ms973231.aspx

What is the difference between a static class and a namespace? (in C#)

The only difference I see is the fact that you can't use the "using staticClass" declaration.
Therefore, I'm wondering:
Is there a real difference between a static class and a namespace?
Is there a possibility to avoid having to rewrite the class name every time a member function is called? I'm thinking about something analogous to "using staticClass".
Yes, a static class is technically a type. It can have members (fields, methods, events). A namespace can only hold types (and it's not considered a "type" by itself; typeof(System) is a compile-time error).
There's no direct equivalent to adding a using directive for a namespace for a static class. You can, however, declare aliases:
using ShortName = ReallyReallyLongStaticClassName;
and use
ShortName.Member
when referring its members.
Additionally, you can use static classes to declare extension methods on other types and use them directly without referring to the class name explicitly:
public static class IntExtensions {
public static int Square(this int i) { return i * i; }
}
and use it like:
int i = 2;
int iSquared = i.Square(); // note that the class name is not mentioned here.
Of course, you'll have to add a using directive for the namespace containing the class to use the extension method if the class is not declared in the root or current namespace.
Static class is still a class. It can contain methods, properties, etc. Namespace is just a namespace. It's just a helper to distinguish between class declarations with the same name.
Function can't live in a namespace alone, it belongs to a class.
Extensions is probably what you are looking for, if you need a static function without mentioning the name of the class.
public static class MathExtensions
{
public static int Square(this int x)
{
return x * x;
}
}
//...
// var hundredSquare = 100.Square();
One other difference is that namespaces can span several assemblies, while classes cannot.
As far as I understand, namespaces are a language feature only; they get removed by compilation. In other words, the .NET runtime does not "see" namespaces, just class names that happen to contain dots. For example, the String class in the System namespace is seen by the .NET runtime as a class named System.String, but there is no concept of namespace at all.
Static classes, however, are fully understood and managed by the .NET runtime. They are fully-fledged types and you can use reflection on them.

Categories

Resources