Understanding namespaces and their use better - c#

One article about namespaces says
Namespaces are C# program elements designed to help you organize your
programs. They also provide assistance in avoiding name clashes
between two sets of code. Implementing Namespaces in your own code is
a good habit because it is likely to save you from problems later when
you want to reuse some of your code. For example, if you created a
class named Console, you would need to put it in your own namespace to
ensure that there wasn't any confusion about when the System.Console
class should be used or when your class should be used.
Now imagine as in above statement I indeed created a Console class inside my namespace called: myNamespace.
Now at some point when someone wants to use say my library, he/she will have to do:
using myNamespace;
but likely she will need to do
using System;
too.
So we still have a clash. If I type Console, which console am I referring to?
How is this problem solved using namespaces?
PS. extra: also how namespaces work under the hood: I remember somewhere I read compiler just prepends functions for example with namespace to find their definitions?
Is this that? Is namespace really nothing just a means to group code?

If you use both of the namespaces, you will either have to fully qualify the usages(System.Console()), or use namespace/type aliases(Console2) to disambiguate the types.
using Console1 = myNamespace;
using Console2 = System;
public void MyMethod()
{
Console1.Console(); // or myNamespace.Console()
Console2.Console(); // or System.Console()
}

You would not include both using statements.
You choose, so your code looks cleaner:
using System;
public static void Main()
{
Console.WriteLine("I'm here!");
myNameSpace.Console.PopBeer("Mo beer!");
}
for practical purposes, if you have a really long namespace, you can use aliases too:
using System;
using sexyNs = myProject.AwesomeSolution.Helpers;
public static void Main()
{
Console.WriteLine("I'm here!");
sexyNs.Console.PopBeer("Mo beer!");
}

The program will not compile. You need to instantiate your classes like this:
System.Console.WriteLine("hi");
myNamespace.Console y = .... ;

a better solution would be to avoid using names which cause conflicts. Name your Console something else so it's clear which one you use when you need to.

#user200300,already many have given exact code solution to your problem description.But let me try to explain clearly.Namespaces also provide assistance in avoiding names clashes.
For example:Lets say there is a single project called Stackoverflow and it contains two teams say TeamA and TeamB.
namespace Stackoverflow
{
namespace TeamA
{
class classA
{
public static void Print()
{
Console.WriteLine("Print A");
}
}
}
}
namespace Stackoverflow
{
namespace TeamB
{
class classA
{
public static void Print()
{
Console.WriteLine("Print B");
}
}
}
}
Here both the team TeamA and TeamB are trying to modify same class classA.Namespaces have helped in organizing the code in efficient and in proper accessible way.
If you want to access the print method from any team you outside these namespaces or from any class for that matter you would write like
Stackoverflow.TeamA.classA.Print();
Stackoverflow.TeamB.classA.Print();
So above code is cumbersome and lengthy and its not clean.Hence aliases can be used .
using STAP=Stackoverflow.TeamA;
using STBP=Stackoverflow.TeamB();
Now you can access easily.
STAP.classA.print();//TeamA's print method.
Thus a namespace can contain Namespace,Class,Inteface,struct,enum,delegate

Related

Is there a reason for giving the class holding Main() a namespace in C#?

After attempting to research C# namespaces further (coming from a c++ background) I think I understand the purpose of namespaces in general - to organise classes for the user, and to avoid conflicts. This practise, I imagine, still holds just as true for programs as it does for libraries.
What I don't understand is why exactly classes housing the Main() function would need to be part of a namespace.
I can't imagine that the main function would need to be called elsewhere for any reason, so organisation and conflict prevention ought not to be the reason.
Is it simply to show other developers what namespace to use throughout the rest of the program's classes? Or is there some deeper reason for it that is going over my head?
What I don't understand is why exactly classes housing the Main() function would need to be part of a namespace.
For sake of simplicity, we're going to assume that the class that contains Main() is called Program.
The Program class does not need to be in a namespace. For example, explicitly declaring the class:
// Program.cs
public class Program {
public static void Main(string[] args) {
System.Console.WriteLine("hi");
}
}
namespace MyNamespace {
public class Data {
public int Val {get;set;}
}
}
or using Top Level Statements
// Program.cs
System.Console.WriteLine("hi");
namespace MyNamespace {
public class Data {
public int Val {get;set;}
}
}
SharpLab (the links above) shows you what the compiler will output, and in both the Program class doesn't exist inside a namespace, even though other classes will.
And for the record, this is not limited to the Program class. You can put any/all of your types in the "global" namespace. You just lose the "categorization" benefit of namespaces.
I can't imagine that the main function would need to be called elsewhere for any reason
I'd agree. Normally you'd let the .Net runtime call your Main method. I'm sure you can think of some reason to do so, but really that's up to the architecture of your application. One maybe valid use case would be automated testing with a testing framework (xUnit, MSTest, etc) in a sibling assembly.
Now, say you did want to call the Main method yourself, as long as the Fully Qualified Type doesn't conflict with something else, you can still call it just like normal.
public class Program
{
public static void DoThing() { }
}
namespace MyNamespace
{
public class Data
{
public void ActivateDoThing() => Program.DoThing();
// or, if you run into a conflict
public void ActivateDoThing() => global::Program.DoThing();
}
}
Is there a reason for giving the class holding Main() a namespace in C#?
This is due to the editor you're using. Except for the Top Level Statements feature, when you create a new project with the "Console Application" template, it will have the Program class wrapped in a namespace, which is consistent with creating a new code file for a new class. This is just a decision the authors of the template have chosen, but at least it does follow the rule that every file has a namespace block. Familiarity can enhance readability, even if its inefficient.
That's really the point of the Top Level Statements feature - get rid of all the boilerplate. Technically, you don't need a namespace for the entry point class - so get rid of it. Most of the time, you don't add anything to Program besides the Main method, so don't require the user typing the class or method signatures. Just let the user get to the Main logic as fast as possible and the compiler can generate the rest.
That's really about it. Why is the namespace there? Mostly for consistency. Does it need to be there? Nope, not at all.

Error :A namespace does not directly contain members such as fields or methods

The following is the "Hello World" program that I tried to get it compiled with, the Microsoft .Net compiler, by the command "cs".
Using System
public class csharp1
{
private static void main()
{
console.writeline("yaaannn");
}
}
But I got the error:
CS0116: A namespace does not directly contain members such as fields or methods
that too at (1,1)
I checked out for this error:
Error "A namespace does not directly contain members such as fields or methods"
In the above question the compilation was being done through "Visual studio ". So , I am not sure if the things about "app.config" file hold good here when the compilation is being done through inbuilt compiler and from command prompt.
Then I checked the following question:
"A namespace cannot directly contain members such as fields or methods" in Net.Reflector
But here as we can see there was a variable which was not enclosed inside the braces of a class, however in this code there was no variable which was out of the confinements of a class.
So, I am unable to know what is causing this problem.
I thought I am missing a semicolon after "Using system " but that too threw the same error.
No capital letter in using, ; after System, and Main with capital M, add namespace:
using System;
namespace Test
{
class csharp1
{
static void Main()
{
console.writeline("yaaannn");
}
}
}
The compiler believes that this:
Using System
... is trying to introduce a new member, but that's not in the context of a type, which is why you're getting that slightly confusing error message. C# is case-sensitive (both for keywords and for method names etc). A using directive needs to be using rather than Using, and it needs a semi-colon at the end:
using System;
Your code still won't compile, as:
Your main method should be Main to be an entry point. It's valid (but unconventional) to have a method called main, but then your program won't have an entry point.
console.writeline should be Console.WriteLine
So a minimal change to make it compile would be:
using System;
class csharp1
{
static void Main()
{
Console.WriteLine("yaaannn");
}
}
I'd also advise you to follow .NET naming conventions, which would name your class Csharp1 (or more conventionally Program for the class containing an entry point). For anything non-trivial, you'd also want to put your class in a namespace, although you don't have to.
C# is case-senstive, so:
Using System
public class csharp1
{
private static void main()
{
console.writeline("yaaannn");
}
}
Should be:
using System;
public class csharp1
{
public static void Main()
{
Console.WriteLine("yaaannn");
}
}

Namespace and Classes - Resolving Naming Ambiguity

The issue I'm getting is "namespace is being used as a type" in a C# project. I get why it's happening and I understand what I have to do to fix it. But it makes little sense to me and so the question here is understanding the design of namespaces and classes in C# context.
I'm hoping this question is different enough from others because I'm not asking how to resolve the situation, but rather how to keep logical and relevant naming while dealing with the situation as I describe it.
I have followed MSDN conventions for naming solutions. So I have a solution called:
TesterStories.Voxam
I have two projects within that. One is TesterStories.Voxam.App and looks like this:
namespace TesterStories.Voxam.App
{
TesterStories.Voxam.Parser parser = new TesterStories.Voxam.Parser();
class Program
{
}
}
The problem is in that third line.
Presumably because I have another project called TesterStories.Voxam.Parser, which looks like this:
namespace TesterStories.Voxam.Parser
{
public class Parser
{
}
}
So is it saying that it doesn't like that I have "Parser" in my namespace for the project?
But according to MSDN guidelines, if the Parser is the feature, then that's what I should be calling the namespace: [Company].[Project].[Feature]. The class is Parser because, after all, that's what the class does.
So it seems like what I have to do is this:
namespace TesterStories.Voxam.Parser
{
public class Xyzzy
{
}
}
So here I changed my Parser class to Xyzzy class. Now back in my file that was causing the problem I can do this:
using TesterStories.Voxam.Parser;
namespace TesterStories.Voxam.App
{
class Program
{
Xyzzy parser = new Xyzzy();
}
}
So I get it -- but it means I have to change my class to be something it's not. I realize I could call it AppParser or ParserApp or whatever.
In this context, what do developers tend to do? Do you change your namespace or do you change your class? Even though, in my case, I'm describing the feature as per MSDN guidelines and correctly naming the class based on what it does.)
The namespaces and class names aren't the problem here.
In your original code, you need to designate what class from the TesterStories.Voxam.Parser namespace this 'parser' object should be.
Your original code:
TesterStories.Voxam.Parser parser = new TesterStories.Voxam.Parser();
What class/type in the TesterStories.Voxam.Parser namespace is this supposed to be?
You would need to do:
TesterStories.Voxam.Parser.*Parser* parser = new TesterStories.Voxam.Parser.*Parser*();
(* added for emphasis :) )
Or, like you did in your last code snippet, add a using statement:
using TesterStories.Voxam.Parser;
So that you can do:
Parser parser = new Parser();
Edit - More complete example (for the 'using' suggestion):
namespace TesterStories.Voxam.App
{
using TesterStories.Voxam.Parser;
class Program
{
Parser parser = new Parser();
}
}
namespace TesterStories.Voxam.Parser
{
public class Parser
{
}
}

Having a Main() routine in a separate file from a Class in C#

I recently branched out into C# written with Visual Studio Express from C++ written with gVIM. I've been told I'll have to unlearn a lot of stuff to really use C# effectively, but here's my question:
In C++ when writing a class or data type, I would have separate files for the class definition and the driver program. I would then #include the class in the driver program in order to use it. It isn't terribly clear how to do this in Visual Studio Express 2013 and all the tutorials I've looked up have the class definition and the Main() routine in the same file.
I currently have only two files in my solution folder: the driver program p1.cs and the type definition/implementation targetInt.cs. What is the best way to allow p1.cs to work with my targetInt.cs type? Will it simply have access by virtue of being part of the same solution? If so, how to I get around not having a Main() routine in my type definition?
Here is a screenshot of the solution and the error I'm getting when I try to build the solution. I don't get an error for trying to declare a targetInt object in p1.cs which points to the namespace already being shared.
http://i793.photobucket.com/albums/yy218/tombombodil/solution_zps6a743e2d.png
Let me know if I need to clarify anything.
It's really not terribly complicated, but it is different from C++. So if you have one file that looks something like this:
namespace MyNamespace
{
public class MyClass
{
//...stuff
}
}
And then you want another file with your Main (which you will for anything more than a trivially simple project), it would look something like this:
using MyNamespace; // unless you use the same namespace for both
namespace SomeOtherNamespace
{
class Program
{
static void Main(string[] args)
{
var c = new MyClass();
// alternatively, without the using statement, you can just fully qualify
// your class name like so:
// var c = new MyNamespace.MyClass();
}
}
}
But do note that the files need to be in the same project. If they are in different projects you can still do it, but you have to add a reference to the project with MyClass to the project with Program. What you can't do is just have an orphaned C# file floating around in your solution and expect it to work.
The problem as you've written boils down to the simple lack of shared namespaces - because targetInit exists in a separate namespace, Program needs a using targetInit.cs to access the targetInit type. They can, however, access each other by virtue of being in the same project - a Solution can contain multiple Projects, and if they don't reference each other, they can't access each other's types.
Usually, the naemspace of any given class is actually the folder path to it, and the class name is the same as the file name (which Visual Studio does for you when you make new class files).
As for the Main() definition, you only want one of these since you only have a single entry point for the system to jump to when your program begins - having multiple Main() functions doesn't make much sense when the OS needs a clear place to begin execution.
The Main() method and class definitions sitting in the same file is a convenience so all the code can be read together - to get an idea for how actual projects are set up, trying going to GitHub and forking a couple of open-source projects.
there are two approaches to use another class in C# directly:
1-putting that class in the same namespace of my class(even if they were in separate files), this code clarify this:
//file TargetInt.cs
namespace MyNameSpace
{
class TargetInt
{
}
}
//file p1.cs
namespace MyNameSpace
{
class p1
{
static void Main(string[] args)
{
}
}
}
notice that both classes are in MyNameSpace namespace.
2-if the other class is contained within another namespace, you can simply use it by declaring this statement in the upper beginning of the file:
//file TargetInt.cs
namespace OtherNameSpace
{
class TargetInt
{
}
}
//file p1.cs
using OtherNameSpace;
namespace MyNameSpace
{
class p1
{
static void Main(string[] args)
{
}
}
}
with using OtherNameSpace; you can use TargetInt class directly.

C# Project & Namespaces Question

I am creating a little Math library for myself contained within a single project and am running into some issues with namespaces. I have the project MyMathLib and the top level namespace:
namespace MyMathLib
{ ... }
and in a separate file...
namespace MyMathLib.Addition
{ ... }
and...
namespace MyMathLib.Subtraction
{ ... }
In the MyMathLib.Subtraction namespace I have a method that needs to use a static method SomeClass.Work() defined in MyMathLib.Addition so I included using MyMathLib.Addition at the beginning of the Subtraction file. But when I try to use the method it would like me to first qualify it with Addition.SomeClass.Work() and I want to be able to just type SomeClass.Work(). What am I doing wrong?
Thanks!
EDIT
Thanks for the suggestions! In each file, I actually named the class after the namespace (i.e. in the namespace MyMathLib.Addition is a static class Addition and in MyMathLib.Subtraction there is a static class Subtraction). Apparently this is what caused the issue (looking back, I should have stated this instead of using SomeClass). If I change the namespace to MyMathLib.MyAddition while keeping the static class as Addition, the using MyMathLib.MyAddition works as I want; that is, I can now just type Addition.Work() in my static Subtraction class. I've seen classes named the same as it's containing namespace before, could someone maybe explain why this is causing an issue? Shouldn't the compiler be able to determine whether I want to use the namespace or the class from the context of the code?
I'm guessing that you either have two classes called SomeClass that are both in namespaces you reference, or you have a variable or property named SomeClass. Either of these situations would make it impossible for the compiler to know that you're trying to call the static MyMathLib.Addition.SomeClass.Work() method, but the specific solution the compiler is suggesting makes it seem more likely to be the former.
Update
Seeing your edit, that makes sense. If you were using these in a namespace outside of MyMathLib, then you would still be able to avoid this namespace conflict. However, because you are inside the MyMathLib.Subtraction namespace, the compiler will implicitly consider any portion of the namespace "above" you to take precedence over class names. In this case, when you say "Addition", the compiler will look for the following items to resolve the name:
A class explicitly identified by a using ... = ... directive.
MyMathLib.Subtraction.Addition namespace.
MyMathLib.Addition namespace.
Addition namespace.
Any classes in the namespaces identified by using statements.
In this case, you're hitting #3 before #4, so you should be able to work around it either by renaming the class or namespace, or by using Yahia's suggestion (#1):
using Addition = MyMathLib.Addition.Addition;
Update 2
After looking at the article you linked to, it sounds like the explicit using statement still won't work. I guess item #1 actually gets evaluated down around item #4 instead. Bummer. You can use an alias to give the class a different name locally:
using Add = MyMathLib.Addition.Addition;
...
var add = new Add();
But the best solution is still probably just to avoid the namespace collision entirely by changing your namespace or class name.
try putting additionally the floowing line into your substraction source
using SomeClass = Addition.SomeClass;
http://msdn.microsoft.com/en-us/library/dfb3cx8s.aspx
http://www.blackwasp.co.uk/NamespaceAliasQualifier.aspx
Sounds like you're in the Subtraction namespace...add this to the top, inside the namespace declaration:
using Addition;
That should do the trick.

Categories

Resources