I've got something like this:
namespace n1
{
namespace n2
{
class foo{}
}
}
In other file I write:
using n1;
Why I can't type now something like:
n2.foo smthing;
And how to make something like this possibile?
This is a deliberate rule of C#. If you do this:
namespace Frobozz
{
namespace Magic
{
class Lamp {}
}
class Foo
{
Magic.Lamp myLamp; // Legal; Magic means Frobozz.Magic when inside Frobozz
}
}
That is legal. But this is not:
namespace Frobozz
{
namespace Magic
{
class Lamp {}
}
}
namespace Flathead
{
using Frobozz;
class Bar
{
Magic.Lamp myLamp; // Illegal; merely using Frobozz does not bring Magic into scope
}
}
The rule of C# that describes this is in section 7.6.2 of the C# 4 spec. This is a very confusing section; the bit you want is the paragraph near the end that says
Otherwise, if the namespaces imported by the using-namespace-directives of the namespace declaration contain exactly one type having name I...
The key point is that it says "exactly one type", not "exactly one type or namespace". We deliberately disallow you "slicing" a namespace name like this when you are outside of that namespace because it is potentially confusing. As others have said, if you want to do that sort of thing, fully qualify it once in a using-alias directive and then use the alias.
Use namespace aliases:
using n2 = n1.n2;
...
n2.foo something;
What is before the class name should be a complete name space (with/or other class name(s) for nested types). A truncated namespace will not work.
By design, namespaces are there to help you define scope.
Unless you fully qualify it, you will get the error you're seeing.
Assuming File1 has something like this:
namespace n1
{
namespace n2
{
class Foo { }
}
}
You can do this two ways:
Fully qualified using
File2 contents:
namespace n3
{
using n1.n2;
class TestClass
{
private Foo something;
}
}
Use a namespace alias
namespace n3
{
using n2 = n1.n2;
class TestClass
{
private n2.Foo something;
}
}
Section 9.4.2 paragraph 4 in the C# language specification explains this behavior explicitly:
A using-namespace-directive imports
the types contained in the given
namespace, but specifically does not
import nested namespaces.
It even goes on to give an example that is very similar to your own.
namespace N1.N2
{
class A {}
}
namespace N3
{
using N1;
class B: N2.A {} // Error, N2 unknown
}
Of course had you done this:
namespace n1
{
public class Example
{
public static void Main()
{
n2.Foo a; // This is legal.
}
}
}
This would compile because n2 is accessible since it is referenced from within an ancestor namespace block.
You cannot write this, as n2 is inside of n1. If you want to access the n2 namespace, you can try typing using n2 = n1.n2 at the beginning of your other file.
One way to do this is to declare your nested namespace as class.
You can have:
namespace NS1
{
public class NNS1
{
public class C { }
}
}
namespace NS2
{
public class NNS2
{
public class C { }
}
}
Then use your namespaces by:
using NS1;
using NS2;
class C
{
public C()
{
var c1 = new NNS1.C();
var c2 = new NNS2.C();
}
}
However, this cannot create union of namespaces. If you have:
namespace NS1
{
public class NNS
{
public class C1 { }
}
}
namespace NS2
{
public class NNS
{
public class C2 { }
}
}
And
using NS1;
using NS2;
class C
{
public C()
{
var c1 = new NNS.C1();
var c2 = new NNS.C2();
}
}
The compiler will complain about NNS for ambiguity, since it can refer to two class symbol in this context. I have tried to declare namespaces as interfaces, and use a class to implement them for creating union of namespaces. However, implementing an interface does not automatically import nested classes symbols in it.
I do not know why C# does not support reference of nested namespace, and I have no idea about the drawbacks for declaring namespaces as classes. Please comment if anyone knows.
Related
I have a class named AuditLog inside Domain.AuditLog namespace. I want to use AuditLog class inside another class with namespace ApplicationServices.AuditLog. like:
using Domain.AuditLog;
namespace ApplicationServices.AuditLog
{
public interface IAuditLogService
{
List<AuditLog> GetAuditLogs();
}
}
It says 'ApplicationServices.AuditLog' is a 'namespace' but is used like a 'type'. I know I can solve this using like:
namespace ApplicationServices.AuditLog
{
using Domain.AuditLog;
public interface IAuditLogService
{
List<AuditLog> GetAuditLogs();
}
}
Is there another way of referencing Domain.AuditLog ?
Maybe this could help you:
using AL = Domain.AuditLog.AuditLog;
namespace ApplicationServices.AuditLog
{
public interface IAuditLogService
{
List<AL> GetAuditLogs();
}
}
I don't understand why an explicit reference isn't required in this situation:
//SomeStaticClass.cs
namespace WhyDontINeedUsingStatement {
public static class SomeStaticClass {
public static string Thingy {
get { return "Behold! A thingy!"; }
}
}
public class SomeNonStaticClass {
public void DoSomethingUseful() {
var foo = 9;
}
}
}
// /SomeNamespace/SomeBoringClass.cs
namespace WhyDontINeedUsingStatement.SomeNamespace {
public class SomeBoringClass {
public static void DoSomething() {
var whatever = SomeStaticClass.Thingy;
var blah = new SomeNonStaticClass();
blah.DoSomethingUseful();
}
}
}
Why doesn't this require a using WhyDontINeedUsingStatement at the top? Aren't these separate namespaces, even though they start with the same thing?
I get that C# namespaces aren't quite the same thing as Java packages (and don't affect access control), but not why the second class is able to reference stuff from the first.
According to C# Language Specification Version 5.0, Section 9.2, it seems like using the . in a namespace declaration is syntactic sugar :
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 {}
}
}
So from inside of N2 you can see N1, hence why you can use it.
I Have created two .cs files with namespaces ,classes and methods . I want to call the classes of one .cs file into another .cs file. Can u help me how to declare namespace and use the namespace so that i can call the classes of the preceding .cs file.
Please forgive if my explanation is not correct.
Suppose i have the following code.
ClassFile1
using system
namespace namespace1
{
class c1
{
Methods()
}
}
ClassFile2
using system
//here i need to declare the namespace1 .Can u help me how to declare namespace1 in this ClassFile2//
namespace namespace2
{
class c2
{
Methods()
}
}
You can reference the fully-qualified name of the class:
namespace SecondNamespace
{
public class SecondClass
{
private FirstNamespace.FirstClass someObject;
}
}
Or you can add a using directive to the file (note, this is at the file level, not the class level) to include a specific namespace when resolving type names:
using FirstNamespace;
namespace SecondNamespace
{
public class SecondClass
{
private FirstClass someObject;
}
}
Taken from here:
namespace SampleNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside SampleNamespace");
}
}
// Create a nested namespace, and define another class.
namespace NestedNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside NestedNamespace");
}
}
}
class Program
{
static void Main(string[] args)
{
// Displays "SampleMethod inside SampleNamespace."
SampleClass outer = new SampleClass();
outer.SampleMethod();
// Displays "SampleMethod inside SampleNamespace."
SampleNamespace.SampleClass outer2 = new SampleNamespace.SampleClass();
outer2.SampleMethod();
// Displays "SampleMethod inside NestedNamespace."
NestedNamespace.SampleClass inner = new NestedNamespace.SampleClass();
inner.SampleMethod();
}
}
}
Note also that sometimes in addition to the "using" entry (I'm not quite clear on how you app is structured, if it's all one project this is probably moot) you may also need to add the reference. Also not sure what environment you're using. From VSExpress while in the project/file that's the recipient click on Project - Add Reference, select solution and then select your namespace.
Is it possible to make the following code valid in C# without changing my namespace or type name. I'm wondering if there is a trick or keyword around this problem?
namespace NS
{
public class Foo { }
}
namespace NS.Foo
{
public class Bar { }
}
The error I'm getting is "The namespace 'NS' already contains a definition for 'Foo'".
No - Imagine having a subclass in Foo called Bar:
namespace NS
{
public class Foo { public class Bar {} }
}
namespace NS.Foo
{
public class Bar { }
}
How can you ever tell the difference if one does: new NS.Foo.Bar()?
Essentially, no there isn't. Even if you could somehow resolve the immediate ambiguity, this problem goes all the way down: what happens if you declare a property of Foo named Bar?
Rename one of your Foos.
No - there's no way to disambiguate from NS.Foo the namespace and NS.Foo the class.
Is there any equivalent to an aliasing statement such as:
// C#:
using C = System.Console;
or:
' VB.NET '
Imports C = System.Console
...but within method scope -- rather than applying to an entire file?
While this might be overkill, you could create a partial class and place only the functions you'd like the alias to apply to in their own file with the alias.
In the main class file:
/*Existing using statements*/
namespace YourNamespace
{
partial class Foo
{
}
}
In the other file:
/*Existing using statements*/
using C = System.Console;
namespace YourNamespace
{
partial class Foo
{
void Bar()
{
C.WriteLine("baz");
}
}
}
Using an object reference would be the logical way. You are putting up a bit of an obstacle by using a static class. Worked around like this:
var c = Console.Out;
c.WriteLine("hello");
c.WriteLine("world");
Or the VB.NET With statement:
With Console.Out
.WriteLine("hello")
.WriteLine("world")
End With
See here and here for more details.
Example:
namespace PC
{
// Define an alias for the nested namespace.
using Project = PC.MyCompany.Project;
class A
{
void M()
{
// Use the alias
Project.MyClass mc = new Project.MyClass();
}
}
namespace MyCompany
{
namespace Project
{
public class MyClass{}
}
}
}