I'm using VS 2017 v15.5.0.
I have a minimal Console project named, Con_02. The namespace for the main class in this project is simply Con_02 (the class is shown below).
Within this project I add a new folder named, Business. Within the Business folder I create a class named, Employee. The default namespace generated by VS for the Employee class is Con_02.Business. I simplify this namespace to Business.
Back in my main class I instantiate Employee. Here is my full main class:
namespace Con_02 {
class Program {
Business.Employee e1 = new Business.Employee();
private static void Main() { }
}
}
So far, so good. Everything compiles.
Now, I create another class, Company, in the Business folder. VS generates a namespace, Con_02.Business.
Now, the main Con_02.Program class no longer compiles. Specifically, the creation of the Business.Employee object which had previously compiled just fine, gives me a compiler error:
The type or namespace name 'Employee' does not exist in the namespace 'Con_02.Business' (are you missing an assembly reference?)
I'm not asking how to fix the problem so much as I'm trying to understand why compiler seems to assume a namespace relative to Con_02.
Since you are creating a new namespace called Con_02.Business which contains Company class the Business.Employee is considered to be under Con_02.Business namespace but Con_02.Business contains nothing but Company class.
Better to change
namespace Con_02.Business
{
class Company
{
}
}
to
namespace Business
{
class Company
{
}
}
or just use Employee e1 = new Employee();
Remember namespace is only about grouping the classes.
Add
using Business;
at the top of you Program class.
and remove The Business-part from your Employee instantiation.
OR. Use the same namespace for all you classes.
Related
I am working with a code base which includes the following class
namespace Api.Data.Models;
// legacy db class entry
public class Log
{
}
and in another class I am constructing a model binder which includes some logging
using Log = Serilog.Log;
namespace Api.Data.Models.Binding;
public class ModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
Log.Information("Trying to call Log.Information");
// This cannot resolve symbol Information as it is still pointing at Api.Data.Models.Log
}
}
I'm not sure if I am trying to do the impossible or if I'm missing something, but why is the aliasing not resolving my name conflict issue in this scenario?
There are other ways to solve my specific problem in the code base but I couldn't find a post or question about this particular case online and hence the question.
The main problem is the namespace nomenclature here.
Your Log class is declared in namespace Api.Data.Models namespace. and ModelBinder is declared in the namespace Api.Data.Models.Binding;.
Api.Data.Models prefix is the same for both the namespaces and that is why it considers your Log class when calling Log.Information("Trying to call Log.Information");.
So you could have a different namespace and your issue will be resolved. like for your Log class use namespace Api.Data.Models.Logs.
Edit:
As mentioned in the comment, If you can not change the Log file then you could change the namespace of ModelBinder class or use a different alias for Serilog.Log. Thank you #Fildorfor pointing it out.
Based on OP's comment the local namespace class always takes precedence over the imported class of the same name regardless of aliasing.
I'm a student learning mainly C++, but this term we have to code our math assignments using C#.
Our professor supplied a basic skeleton program but I'm not very good at C#. He gave us two class files (.cs) but when I add them to my project, I'm unable to utilize them at all. I can't create a class object from either class.
The classes are just Line3d and Point3d. They have the variables needed to compute points and collision.
Thanks for any advice.
Compile your project.
Use Ctrl + . or bulb icon (type your class name you want to use and locate your cursor position over that class name) to resolve namespace for these classes or write using directive manually.
C# classes are normally encapsulated in namespaces. In Visual Studio, adding a new class will generate a file containing a namespace similar to PROJECT_NAME.SUBFOLDER.SUBSUBFOLDER For example:
// MyClass.cs
using System;
namespace MyProject
{
public class MyClass
{
}
}
And then you can reference that from another class in the same namespace, but you can't reference it from a class in another namespace (unless it's a namespace that starts with MyProject.).
// Line3d.cs
using System;
namespace TemplateProject
{
public class Line3d
{
}
}
// MyClass.cs
using System;
namespace MyProject
{
public class MyClass
{
public Line3d LineInstance {get;set;}
}
}
In this example, it won't work because the compiler doesn't know which namespace Line3d exists in (and, indeed, two class with the exact same name could exist in two different namespaces). You need to instruct the compiler to include classes from the TemplateProject namespace (note this doesn't include classes in the TemplateProject.ChildNamespace namespace):
// MyClass.cs
using System;
using TemplateProject;
namespace MyProject
{
public class MyClass
{
public Line3d LineInstance {get;set;}
}
}
Now you should be able to find the Line3d class and use it.
Besides manually referencing the namespace, you can also right-click an unknown class reference, select "Quick actions and Refactorings...", and then you will see something like "using TemplateProject;". Click on this and it will automatically add the using for you.
You can also use the Ctrl+. keyboard shortcut, which does the same as right-click/Quick actions, if you don't want to use the mouse.
select your project and press [ Shift + Alt + A ] to add existing files.
you can see dialog form that allows to open cs file on project.
After that, you can use professor's class files.
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
I have a few differenet namespaces in my solution and I want to use an object called "Doctor" from namespece BL_Backend inside another namespace called DAL. I've tried adding a Refference to DAL (a refference for BL_Backend), and then adding "using BL_Backend;" but it wouldn't work. still classes such as Doctor won't appear as known ones inside namespace DAL.
namespace BL_Backend
{
…
namespace DAL
{
…
//Here create object as "Doctor" for BL_Backend class
}
}
For example,
when i call a constructor of a doctor from DAL it says this constructor does not exists but when i write the exact same command at namespace bl_backend it works fine.
thanks alot!
I assume Doctor is declared as internal class in BL_Backend assembly. Note - if class does not have public access modifier, then by default it will be internal:
namespace BL_Backend
{
class Doctor // this class is internal
{
}
}
Internal classes are visible only within assembly they are defined (well, there is attribute InternalsVisibleTo which allows other assemblies to see internal classes, but without applying this attribute, class is not visible to other assemblies).
If you want to use a class Doctor from an assembly BL_Backend in a DAL you must add a reference in DAL to the BL_Backend not vise versa.
Classes without a modifier are internal by default, so ensure that your modifier is public.
As a second option pay attention to the build order - its not a problem in VS12+ anymore, but in further versions it was.
I have a webservice project with a class (let's refer to it as webservice.classA).
I have another class project producing a dll which references that class in its own namespace and instantiates an instance of it (lets call the dlls namespace dllnamespace).
In another project I want to access the member in the dll
e.g.
using webservice;
namespace other_project
{
class B
{
classA copy = null;
//....
dllnamespace.dostuff(); // amongst other things instantiates a classA object
//....
copy = dllnamespace.getclassA(); // method to return classA member
The compiler error I get is cannot convert type from dllnamespace.webservice.classA to other_project.webservice.classA
I guess I have a fundamental design flaw but I figure there must be (?) a way to declare/use "webservice.classA" in more than one namespace.
You have a name clash. The supported way of avoiding this (short of not naming your classes the same), is to define a using alias for one of the classes:
using webservice.classA = myWebserviceClassA;
You are right...the design flaw does exist in terms of naming.
Let us assume:
you have a class named
MyClass
the class exists both in namespace- abc.xyz.qwe.tyu.MyClass
and in namespace - sed.qwe.dfg.ert.MyClass
The workaround is -
using NS1 = abc.xyz.qwe.tyu.MyClass;
using NS2 = sed.qwe.dfg.ert.MyClass;
This way you avoid the clash.
Also, helpful to use if you have very long namespaces.
FURTHER REFERENCE : (From MSDN article on using Directive )
The scope of a using directive is
limited to the file in which it
appears.
Create a using alias to make it easier to qualify an identifier to a
namespace or type.
Create a using directive to use the types in a namespace without having to specify the namespace. A using directive does not give you access to any namespaces that are nested in the namespace you specify.
Change the copy definition line to:
dllnamespace.webservice.classA copy = null;
That's just the problem - you cannot have a class in more than one namespace. This is what namespaces were designed for - to prevent classes with the same name written by different people from aliasing. You'll need to decide for one of your namespaces to own that class and in the other one to import it. Alternatively if the dll and the web service are part of the same distributed app then they should use the same namespace.