I always right click to resolve the namespace implicitly.
But for some namespace, I cannot resolve it implicitly and have to resolve it explicitly, leading to code like program1.logging.ErrorLogger.ErrorArise. Why can't I resolve implicitly?
Check this fiddle:
https://dotnetfiddle.net/6Px9BQ
The problem is, there are two or more classes sharing the same name, so its not implicitly possible to know which you refer to, hence you need to specifiy the name explicit, by providing its full namespace name.
If you dont want to specify long qualifiers all the time, you can shorten them like this:
Apple.Berry.Cheese.Cake cake = new Apple.Berry.Cheese.Cake();
shortened:
using abc = Apple.Berry.Cheese;
abc.Cake cake = new abc.Cake();
Visual studio gives you a lot of power and can easily let you pass over some concepts. One of the tools provided is that you can right click to add a using directive at the top of the code file which signals the compiler what class names will mean at compile time.
But if two namespaces have the same class name, and both are in use in the same class, then you have to explicitly tell the compiler in each case what to use.
Related
There is something I don't understand with the NuGet package CommandLineParser. This is the first time I see this?
Let me show you first:
On the left in my Auto Watch frame I can see the Value property. But, on the right, in Immediate Window I cannot access it. How is this possible. How can I use this package and read my Value Path after Parsing?
result.Value
error CS1061: 'ParserResult<Options>' does not contain a definition for 'Value' and no accessible extension method 'Value' accepting a first argument of type 'ParserResult<Options>' could be found (are you missing a using directive or an assembly reference?)
What is this watch folder doing I'm not doing?
By digging into the source code, you can see that ParserResult<T> is an abstract class..
The WithParsed extension method does a check to see if the ParserResult is a concrete type of Parsed, invokes the delegate and returns it https://github.com/commandlineparser/commandline/blob/master/src/CommandLine/ParserResultExtensions.cs
So now you're working with the abstract base class instead of the implementation, that's why you can't just do result.Value as that property is not sitting on the base class but rather the implementation.
My guess is that the Auto watch can know the actual type and show you the entire object and the Immediate window can't.
To work with .Value, you can cast it to Parsed<Options>
The exact example of using this CommandLineParser is used in this project: https://www.dropbox.com/s/nhq9os8dd9fim9u/FloorplanTransformation-3D-Walls.rar?dl=0
This is a visual studio project, check that out you will get a better understanding.
By the way here is a brief explanation:
you will have to create an instance of the Parser class.
Parser parser = Parser.Default;
Then to parse the arguments do the following
PraserResult<object> parser_result = parser.ParseArguments<MeshGenerateOptions, MorphologicalTransformOptions, other options>(args)
Here we have classes MeshGenerateOptions and MorphologicalTransformOptions with Attribute [Verb]
Now do the following to invoke the corresponding callback functions for each parsed arguments
parserResult.WithParsed<MeshGenerateOptions>(VerbHandlers.HandleGenerateMesh);
parserResult.WithParsed<MorphologicalTransformOptions>(VerbHandlers.HandleMorphologicalTransform);
Here, VerbHandlers is a static class not of much interest, HandleGenerateMesh and HandleMorphologicalTransform are Callback functions that are invoked when the corresponding verb is parsed.
You get the demo of How to use the above project you can watch the tutorial: https://www.youtube.com/watch?v=MNILyflAxdY&t=21s But this is just for building and using the above project.
I'm working on a C# library (let's just call it "Foo" for the sake of this question). It has some needs very similar to standard .NET needs: for example, it provides some drawing services, and some conversion services.
For the sake of familiarity and users of the library being able to guess what things are called, I'd like to follow the .NET standard, and name these parts of the library Foo.Drawing and Foo.Convert (and so on). But I'm finding that in actual use, this causes pain. People almost always have "using System;" at the top of each file, and when using this library, they want to have "using Foo;" as well. But now they have two Drawing and two Convert modules, and hilarity ensues.
For example, now instead of just using Drawing.Color for a parameter or variable type, you have to explicitly spell out System.Drawing.Color, or the compiler complains that Foo.Drawing doesn't have a Color type. Similarly, you want to use a standard Convert.ToInt32, you have to say System.Convert.ToInt32, even though you're already using System, because otherwise it finds Foo.Convert and fails to find ToInt32.
I understand why all this is as it is, but I'm still new to the C# community, so I don't know which is the most standard solution:
Leave it this way, and expect users to use fully-qualified names where necessary?
Rename the conflicting modules to something else (maybe Foo.Graphics instead of Foo.Drawing, and Foo.Conversion instead of Foo.Convert)?
Use some prefix on the standard names (Foo.FDrawing and Foo.FConvert)?
Something else?
Any advice from you more experienced C# gurus will be appreciated!
You can use namespace aliasing :
using System;
using FConvert = Foo.Convert;
public class Bar
{
public void Test()
{
var a = Convert.ToInt32("1");
var b = FConvert.ToInt32("1");
}
}
One of the main usage of namespaces is to avoid name clashing.
It means that namespaces allow developers to create types with identical names, as long as the belong to different namespaces.
A library usually have at least a root namespace, and possibly nested namespaces that logically groups the related types.
Name your types as you wish, as long as the names are meaningful and represent what the type really are. A client of your library expects a type named Animal to represent an Animal, not something else. The same applies for naming namespaces.
However, avoid at all cost the names from System, since it will be really annoying for your library clients (as you described) to deal with conflicting names all over the place.
A common way to deal with conflicting namesapces inside a class is to use namespace aliasing:
using FooConvert = Foo.Convert;
using BarConvert = Bar.Convert;
I am trying to create a common library structure. I am doing this by creating separate projects for every common lib I want.
I have the following 2 namespaces: MyCompany.ERP and MyCompany.Barcode
I need both of them to have a class named Utilities and be static. If I do that I will then need to specify the full namespace name before my static class in order to access it.
Is there any other preferred way to do it?
Or I should go for different names in classes like BarcodeUtils and ERPUtils?
If i do that i will then need to specify the full namespace name before my static class in order to access it?
No, there is no need for that, though the details depend on the class that will use these types and the using declarations it has.
If you only use one of the namespaces in the class, there is no ambiguity and you can go ahead and use the type.
If you use both of the namespaces, you will either have to fully qualify the usages, or use namespace/type aliases to disambiguate the types.
using ERPUtils = MyCompany.ERP.Utilities;
using BCUtils = MyCompany.Barcode.Utilities;
public void MyMethod()
{
var a = ERPUtils.Method();
var b = BCUtils.Method();
}
There isn't any other way. You can make an aliases in using directives:
using MC=MyCompany.ERP;
using MB=MyCompany.Barcode;
...
public void Test()
{
var a = MC.Utilities.Method();
var b = MB.Utilities.Method();
}
It's the simplest way to manage them.
The MS guidelines have the following to say:
Do not introduce generic type names such as Element, Node, Log, and Message. There is a very high probability it would lead to type name conflicts in common scenarios.
and
Do not give the same name to types in namespaces within a single application model.
I concur that it's probably a good idea to use BarcodeUtilities and ErpUtilities instead. (Unless the utility classes are not meant to be used by client code, in which case you could name them Utilities and make them internal.)
"Utilities" is not a very good name for a class, since it is far too generic. Therefore, I think you should rename both of them to something more informative.
You can use an alias:
using BarcodeUtils = MyCompany.Barcode.Utilities;
on the pages you have clashes. But ideally rename them if this is happening in a lot of places.
I would suggest using different class names. If you really want to call both of them Utilities then you could use the alias feature on the using directive, e.g.
using ERP = MyCompany.ERP;
using Barcode = MyCompany.Barcode;
...
ERP.Utilities.SomeMethod();
Barcode.Utilities.SomeMethod();
You will have to use the full path when both are named the same. Otherwise you will get an ambiguous reference error.
You can use an alias however that will save you some typing:
using Project = PC.MyCompany.Project;
I would go for a different name that's somewhat more descriptive. A
It actually depends on the purpose of your classes. If you are going to distribute your Barcode.Utilities and ERP.Utilies seperately it is better stay like this. On the other hand, if you are going to use them only in same class, you may use 2. method for easiness of code.
I am very new to c# and this is probably a very n00b error.
For this project I have been handed existing code to work with. The structure of the code is that it has a main solution with simulation as a supporting namespace.
I copied one of the classes (Adt_12) from simulation namespace that I want to modify and renamed it (Pb_cs2). The way I copied is, was to click on save as.. and then changed the file name to the new name I want. And then changed the public class name (and the constructors) to this new file name. I have rebuild 'simulation' and it rebuilts fine.
But when I try to call Pb_cs2, it is throwing the above 'the type or namespace named Pb_cs2 could not be found'.
The way I am using it in the executable class in main; is
public static Pb_cs2 pb; (which was originally using Adt_12).
But it can still find Adt_12 in the solution and namespace. Just no Pb_cs2. I have rebuilt and built the solution.
The common error of .NET framework is not relevant.
Any ideas why this is happening and how I can fix this? I really dont want to modify the original file.
Take a look here. Visual Studio saying name doesn't exist in current context
You need to make sure:
Your class name and namespace are not the same, like Pb_cs2.Pb_cs2 as this will confuse the compiler
You can fully qualify the path to the class i.e. MyNamespace.MyNestedNameSpace.MyClass
You can use a shortcut i.e. using MyClass = MyNamespace.MyNestedNamespace.Class1
Ensure that your projects are targeting the same framework i.e. .NET 4.0 / .NET 4.0 Client Profile.
You might have a collision where your class has the same name as another class, in which case, use option 2, or rename your class to something else.
If your class name does not appear in intellisense, then it does not know where to look for it. You can right click the class and click "Resolve" which will give you some options on how to qualify your class.
...that is all I can think of right now!...Good Luck!
Edit:
Look up C# stylistic conventions... those class names are ugly!!!
Add a reference to the namespace which contains the class you are calling. So you might have something like
namespace SomeNamespace
{
public class Pb_cs2
{
...
}
}
so you need to add using SomeNamespace; to the declarations at the top of the file that is attempting to call your class. Or call the class using the fully qualified name
SomeNamespace.Pb_cs2 pbcs2 = new SomeNamespace.Pb_cs2();
You can also create a alias to the namespace when you reference it like
using NS = SomeNamespace;
then the above explicit reference can be called like
NS.Pb_cs2 pbcs2 = new NS.Pb_cs2();
I hope this helps.
Do it this way to be sure the calss is known by your solution.
Project->addclass
select class if it isn't selected by now.
Name it and then add the new class.
it should appear in your solution explorer.
Now copy paste the code. rename the class the namespace should be fine.
and you should be okay with that.
Quick and simple question. I kind of understand what the Namespace Alias qualifier does, it's for accessing members in a namespace, however so does the dereferencing operator. I am really baffled as to the difference in this situation, why you would use one over the other, or how they each accomplish the same thing.
using colAlias = System.Collections;
namespace myns
{
class TestApp
{
static void Main()
{
colAlias.Hashtable test = new colAlias.Hashtable();
colAlias::Hashtable test1 = new colAlias::Hashtable();
}
}
}
This is a corner case :: (like the # prefix) is there to deal with the fairly rare occurrences where a name conflicts between namespaces, classes and keywords.
:: only works for namespaces (and namespace aliases), while .. works for both namespaces and subclasses. Most places where you'd need it you'd be better off using a different name instead, but that isn't always an option.
global:: is a special case that's most often seen in auto-generated code - it resets the referenced namespace to the root.
For instance, suppose you auto-generate some code (maybe for a forms app, EF, or similar) and your app uses the namespace YourCompany.Application. Now one of your customers (using your auto-generation) decides to add their own namespace in their app TheirCompany.YourCompany.Application. Now all your auto code fails because when it compiles .Net doesn't know whether to use your namespace or theirs.
To fix this generate code with global::YourCompany.Application, then those that use your auto-generator can use whatever namespace they like and not conflict.
I think Microsoft added global:: because they expected some .Net customers to add namespaces like System.
You said:
Namespace Alias qualifier does, it's for accessing members in a namespace, however so does the dereferencing operator.
Well, no. The . operator is used to access any member, including functions. You cannot do Console::WriteLine();
:: is only for resolving namespaces, either from a namespace alias like this:
using colAlias = System.Collections;
...
...
colAlias::Hashtable test = new colAlias::Hashtable();
OR from global.
global::System.Console.WriteLine(..);
You cannot do :
System.Collections::ArrayList a = new System.Collections.ArrayList();
BUT, if you have an alias the . operator also works, so in your case, there is no difference.
There's an MSDN page explaining how this works.
Basically, in your situation they will achieve the same thing and for code readability it's preferred to use a single ..
I wouldn't use the :: operator on anything but the global namespace, and even then there are more than enough ways to work around it.
edit: More information what the operator does is explained at the :: Operator (C# Reference) article.
The general idea of a namespace qualifier is to allow you reference the namespace even if the name has been used elsewhere. If you declared a class named "colAlias" then colAlias.Hashtable would reference the class but colAlias::Hashtable would reference the namespace'd value.
This is a fairly narrow use-case and global:: is the only typical use case I have seen for this operator (When trying to ensure no conflicts can occur when creating generated code to be compiled in an unknown application).
The namespace alias qualifier (::) helps you to access namespace methods without causing errors if you have CONFLICTING namespaces using the same naming convention.
For example as explained here in msdn
http://msdn.microsoft.com/en-us/library/c3ay4x3d(v=vs.80).aspx