Namespace and class have the same name - c#

I have inherited a large c# project. One of the classes has a namespace and class which share the same name. As a result when making an instance of the class i have to do this:
using xxx.existingName
IinterfaceName dog = new existingName.existingName();
Since the existing class has an interface i am able to avoid having existingName.existingName on the left of the =. Using var dog would also do this. However i also want to avoid existingName.existingName being used on the right hand side because it is less readable.
Is there any way to do this without renaming the existing code?

You could rename the class or the namespace via the using directive:
using ClassAlias = Test.Test;
using NamespaceAlias = Test;
public class Program
{
public static void Main()
{
ClassAlias a = new ClassAlias();
NamespaceAlias.Test t = new NamespaceAlias.Test();
}
}
namespace Test{
public class Test{}
}

You could use an alias to make this more readable(well, not with these names):
using AliasForName = existingName;
...
IinterfaceName dog = new AliasForName.existingName();
If the original author would have looked at this MSDN article, he would have used a different name in the first place:
X DO NOT use the same name for a namespace and a type in that
namespace . For example, do not use Debug as a namespace name and then
also provide a class named Debug in the same namespace. Several
compilers require such types to be fully qualified.
By the way, you should really apply capitaliation conventions.

Related

A namespace cannot directly contain members such as fields, methods or statements in .Net 6 [duplicate]

My understanding is that it is similar to write code directly into the old "static void Main(string[] args)" without the need to display what's above.
However, I used to declare my variables in the class Program to have them accessible from other classes (apologies if not best practice, I learnt C# by myself and as long as it works, I'm happy with my code).
See example below:
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
namespace myNameSpace
{
class Program
{
//variables declaration
public static string abc = "abc";
public static int xyz = 1;
static void Main(string[] args)
{
//code goes here
}
}
}
With C# 9, it seems I can only declare variables in the Main section, so how can I declare them to be able to access them from other classes?
I don't think the currently-accepted answer is correct, if you toss a partial class signature in Program.cs you can most certainly add things like static-scoped fields and attributes:
var customAttributes = (CustomAttribute[])typeof(Program).GetCustomAttributes(typeof(CustomAttribute), true);
Console.WriteLine(customAttributes[0].SomePropery);
Console.WriteLine(MyField);
[Custom(SomePropery = "hello world")]
public partial class Program
{
private const string MyField = "value";
}
class CustomAttribute : Attribute
{
public string SomePropery { get; set; }
}
The above code and nothing else in Program.cs will output:
/home/dongus/bazinga/bin/Debug/net6.0/bazinga
hello world
value
Process finished with exit code 0.
I use this method to apply the [ExcludeFromCodeCoverage] attribute to my projects' Program.cs files
For .Net 5:
When you use the Top-Level Program feature of C# 9, you give up the ability to put anything outside the Main method scope. Fields, properties, attributes on the Main method or Program class, setting the namespace, changing the class name, etc are all no longer available (the only exception is "importing" namespaces with using lines).
If that limitation doesn't work for you, don't use the feature.
For .Net 6 and higher, use dongus's answer.

Why does VS-Intellisense sometimes "use" the namespace and prepend it to a type in C#

Why does VS-intellisense sometimes write using at the top of the page and sometimes adds it inline like new namespace.class in C#?
For example
using Namespace;
Obj obj = new Obj();
and
obj = new Namespace.Obj();
Sometimes two namespaces have the same class. So to avoid ambiguity the namespace is added to the class .
Example:
Imagine that you have Namespace1 and Namespace2 and both of them has the class Employee
using Namespace1;
using Namespace2;
namespace MyNamespace
{
public class MyClass
{
private Employee emp1; // does it come from Namespace1 or Namespace2 ?
}
}
So two solutions can be done in this case
one is to have the name space explecitly defined
using Namespace1;
using Namespace2;
namespace MyNamespace
{
public class MyClass
{
private Namespace1.Employee emp1;
}
}
and the other is that you define from the beginning that you are using the Employee from a certain namespace as follows.
using Namespace1;
using Namespace2;
using Employee = Namespace1.Employee;
namespace MyNamespace
{
public class MyClass
{
private Employee emp1; //Notice the definition above
}
}
Visual Studio 2015 has a bug where it does this.
Whether or not you include a using statement at the top of your code file, the bug causes it to add the namespace in front of your definition.
I asked a similar question a few weeks ago and, on the recommendation of another user, submitted an issue on the relevant github project.
My issue was closed almost immediately with a rather snippy comment which basically said "update to Visual Studio 2017 because we fixed it in that version".

Why can't i use partly qualified namespaces during object initialization?

I suspect this is a question which has been asked many times before but i haven't found one.
I normally use fully qualified namespaces if i don't use that type often in the file or i add using namaspacename at the top of the file to be able to write new ClassName().
But what if only a part of the full namespace was added ? Why can't the compiler find the type and throws an error?
Consider following class in a nested namespace:
namespace ns_1
{
namespace ns_1_1
{
public class Foo { }
}
}
So if i now want to initialize an instance of this class, it works in following ways:
using ns_1.ns_1_1;
public class Program
{
public Program()
{
// works, fully qualified namespace:
var foo = new ns_1.ns_1_1.Foo();
// works, because of using ns_1.ns_1_1:
foo = new Foo();
}
}
But following doesn't work:
using ns_1;
public class Program
{
public Program()
{
// doesn't work even if using ns_1 was added
var no_foo = new ns_1_1.Foo();
}
}
it throws the compiler error:
The type or namespace name 'ns_1_1' could not be found (are you
missing a using directive or an assembly reference?)
I assume because ns_1_1 is treated like a class which contains another class Foo instead of a namespace, is this correct?
I haven't found the language specification, where is this documented? Why is the compiler not smart enough to check if there's a class or namespace(-part)?
Here's another - less abstract - example of what i mean:
using System.Data;
public class Program
{
public Program()
{
using (var con = new SqlClient.SqlConnection("...")) // doesn't work
{
//...
}
}
}
Edit: now i know why this seems very strange to me. It works without a problem in VB.NET:
Imports System.Data
Public Class Program
Public Sub New()
Using con = New SqlClient.SqlConnection("...") ' no problem
End Using
End Sub
End Class
This obvious way unfortunately not working but you can make all this by an alias namespace:
using ns_1_1 = ns_1.ns_1_1;
public class Program
{
public Program()
{
var no_foo = new ns_1_1.Foo();
}
}
The documentation says:
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.
So the using only includes the types (not the namespaces) that are defined in the specified namespace. In order to access types of nested namespace you need to specify it explicitly with a using directive as you did in your first example.
This is documented in the standard in 3.8 Namespace and Type Names, but it's a bit convoluted to follow.
The gist of it that a partial namespace reference is only looked for in the namespace where it occurs, and each layer outwards. using-directives are not checked.
In your example, ns_1_1.Foo would be found if Foo is found anywhere in:
Program.Program.ns_1_1.Foo
Program.ns_1_1.Foo
ns_1_1.Foo
Partial namespaces will work only if your current class is part of that partial namespace. Using statements are not considered for accessing types through partial namespace.
For instance this will work because your current namespace is ns_1
namespace ns_1
{
public class Program
{
public Program()
{
var no_foo = new ns_1_1.Foo();
}
}
}

Why do I need fully qualified name to access static property of a class that was included with "using"

If I have this class declaration
namespace DatabaseCache
{
public class DatabaseCache
{
public static bool somePublicFlag ;
}
}
In another class I have this statement
using DatabaseCache;
Why do i need to write a statement like this in that class
DatabaseCache.DatabaseCache.somePublicFlag = true ;
instead of just
DatabaseCache.somePublicFlag = true ;
You don't need that if you don't have a Namespace and Type name collision. A well designed library will not have such collision, So design your library accordingly to avoid such collision.
namespace DatabaseCache
{
//change the name of the class
public class DifferentNameThanNamespace
{
public static bool somePublicFlag ;
}
}
Because the compiler doesn't know if DatabaseCache is referring to the namespace or the class. Even thought you're using the namespace it's still perfectly legal to preface types within that namespace by the namespace, so the call is ambiguous.
You could alias the type by using:
using DC = DatabaseCache.DatabaseCache;
and then just calling
DC.somePublicFlag
but that's just masking the problem - renaming the namespace is a better solution.
In order to avoid ambiguities, it is not recommanded to declare a class with the same same as its namespace.
The Framework Design Guidelines say in section 3.4 “do not use the same name for a namespace.
To learn about how to activate/disable this kind of warning see this link
(Of course the advice is to not use the same name for two distinct things.)
Answer with an extension. Suppose you have one file with:
namespace DatabaseCache
{
public class DatabaseCache // same name as namespace :-(
{
public static bool somePublicFlag;
}
public class somePublicFlag // evil other type
{
}
}
Then now it depends on where you put your using directives relative to your namespace. For example, in another file, this will be legal:
namespace Other
{
using DatabaseCache;
class DbcTestClass1
{
void M()
{
DatabaseCache.somePublicFlag = true; // legal!
}
}
}
In the above example, somePublicFlag refers to the field of the class!
However, this is legal as well:
using DatabaseCache;
namespace Other
{
class DbcTestClass2
{
void M()
{
var instance = new DatabaseCache.somePublicFlag(); // legal!
}
}
}
With that placing of the using directive, the somePublicFlag refers to the "evil" class of that name. The qualifier DatabaseCache. in this case is redundant, but it is still seen as a reference to the namespace global::DatabaseCache because the global namespace (null namespace) is searched first in this case.
To learn more, see my answer elsewhere. It all depends on the order in which the different namespaces (including the global namespace) are searched for a matching name.

how to use a new class method in other apps?

I used this code in c++ to use a class (that I defined before)in my other Apps.
#include class_name ;
How can I define a public class that could be used in all apps?
Thanks
To access classes from external assemblies you must add a reference to an external assembly. This will allow you to access public classes from the external assembly.
To specify a class from a namespace outside your current scope you must prefix the class's type specifier with its namespace name. To avoid this overhead, you can "include" the external namespace with the using directive.
Multiple namespaces can exist within a single assembly.
Assembly Fruit:
namespace Common
{
public class Strange
{
var mystery = new Mystery() // Won't compile, no reference to Mystery.
}
}
namespace Fruit
{
public class Orange
{
}
}
Assembly Vegetables:
References Fruit
namespace Common
{
public class Mystery
{
}
}
namespace Fungi
{
public class Mushroom
{
}
}
namespace Vegetables
{
using Common;
public Class Carrot
{
var strange = new Strange() // Compiles correctly.
var mystery = new Mystery() // Compiles correctly.
var orange = new Orange() // Won't compile, what's an Orange?
var orange = new Fruit.Orange() // Compiles correctly.
var mushroom = new Mushroom() // Won't compile, what's a Mushroom?
var mushroom = new Fungi.Mushroom() // Compiles correctly.
}
}
You need to create a Class Library project, which compiles to a DLL file.
You can then add a reference to it in other projects.
You have to include the namespace as below and also add any references if in another project.
using class_namespace;
If the other class is public or internal (and in the same assembly if they are internal), is in the same project, and has the same namespace, then you don't need to do anything at all. You will be able to refer to the other class by just using it's class name.
If they are in different namespaces then you can use a using statement (at the top of the file) to bring the other namespace into scope, or you can refer to the other class using the fully qualified name (i.e. OuterNamespace.InnerNamespace.ClassName) every time you use the class. (Which almost nobody ever does, everyone just uses using statements because they are so much more convenient.)
If the class is in another project entirely then you will need to add a reference to that class through visual studio. If you are creating a project that is designed to be referenced by other projects then it's project type should be a "class library".
Every class is created under a namespace
namespace abc{
public MyClass{
//functionality
}
}
To use your class on a different application,you need to import the namespace.
using abc;
public class usingClass{
MyClass obj = new MyClass();
}

Categories