When upgrading project from 3.5 to 4.0 I encountered the collision of ISet class that exists in both
namespace:
System.Collections.Generic
Iesi.Collections.Generic
I have those two classes in hundreds of files. Prior to 4.0 there was not ISet in System.Collections.Generic.
How would you solve this pain ... ? Should I really add to each file: Iesi.Collections.Generic to ISet?
or give an alias:
using IesiGeneric = Iesi.Collections.Generic;
and use like that: IesiGeneric.ISet but all these means I have to change all those files ....
Is there another option?
UPDATE
What about creating interface like this:
using System;
using System.Linq;
using System.Text;
using Iesi.Collections.Generic;
namespace NameSpace
{
public interface IesiSet<T> : ISet<T>
{
}
}
and change Iesi Iset's to: IesiSet?
You should be able to add an alias directly to the type:
using ISet = Iesi.Collections.Generic.ISet;
Which should mean you ONLY need to update the head of each file.
However, going forward, I expect overtime (particularly as personnel changes) this is going to become a maintainability gotcha as people assume this is the built in ISet. I would take the pain now and replace globally now.
[also
I encountered the collision of ISet class that exists in both namespace
System.Collections.Generic.ISet is an interface. If your version is a class I would consider taking the pain of renaming it now, as it looks like an interface name]
Related
I have been looking around for a while now to see how can I enforce my C# projects to have full namespace path.
For example actual if namespace for class X is Foo.Bar.Car.Dealer when doing Ctrl+. in visual studio it sometimes puts statement like using Car.Dealer; this specially becomes a problem with multiple projects solution. I have been looking around for StyleCop rule or something that might help me get this done.
Any help or ideas?
EDIT
The above statement holds true only if the using class falls under same namespace prefix. Here is complete code example:
File: X.cs
namespace Foo.Bar.Car.Dealer {
class X {}
}
File: UsingClass.cs
namespace Foo.Bar.Another.ClassPath {
using Car.Dealer;
class UsingClass {
private X _x;
}
}
The VS picked using Car.Dealer but I want to enforce using Foo.Bar.Car.Dealer
I do not know about versions prior to 2012, but from then on the icon that pops up for action upon coming across an unknown type offers both adding the namespace via using directive or to simply prefix the type being referenced by the full namespace.
If you do not want to add the namespace via using directive (which would look like using Foo.Bar.Car.Dealer;),
then in your example you simply need to reference your type X as Foo.Bar.Car.Dealer.X.
Example:
//assuming your X type is instantiable
Foo.Bar.Car.Dealer.X myX = new Foo.Bar.Car.Dealer.X();
I am working on a T4 template which produces partial classes based on existing partial classes.
Sometimes the generated code will reference types being used from the existing (non-generated) codebase.
The generated code must either fully qualify these types, or mimic the using statements it finds in the non-generated code.
Mimicking using statements seems better since it will support cases where the type is being referenced from a [Attribute(typeof(Something))], where EnvDTE only returns the string literal "typeof(Something)".
So: how do I find these using statements? I'm using tangible T4's AutomationHelper, but still can't seem to find a solution :(
You can get the using statements by looking at the FileCodeModel.CodeElements for the ProjectItem.
Each ProjectItem has a FileCodeModel property. The FileCodeModel.CodeElements will contain a CodeImport for each using statement. Note that the FileCodeModel.CodeElements will contain other things not just CodeImportss o you will need to check the type returned or filter the unwanted types.
An example is shown below. Here I am using the NuGet's Package Manager Console and PowerShell.
$p = Get-Project
$fileCodeModel = $p.ProjectItems.Item("Class1.cs").FileCodeModel
$fileCodeModel.CodeElements | % { $_.Namespace }
The code above assumes there is a Class1.cs file in the root of the project. For each using statement it will print the full namespace. Note that in the above code it is trying to print the Namespace for each CodeElement and some of the elements will not have this property so you will need to restrict this so it only looks at CodeImport types. The above will work for the following class file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassLibrary1
{
public class Class1
{
}
}
If you have using statements between the namespace ClassLibrary1 and the public class Class1 part you will need to do more work and look at the CodeNamespace members since the CodeImports will not be available directly from the FileCodeModel.CodeElements, but hopefully the above code should point you in the right direction.
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.
I have two Reason classes:
1. One that generated by the edmx file and inherited by the object context.
2. One that I created as POCO object.
While I write my queries I need to write the full namespace of the Reason POCO class:
using System.Collections.Generic;
using System.Linq;
using MyProj.Domain.Business.EntitiesRepository.System.Calls;
namespace MyProj.Data.EF4.EntitiesRepository.System.Calls
{
public class ReasonRepository:
EFRepository<MyProj.Domain.Business.Entities.System.Calls.Reason>, IReasonRepository
{
public IList<MyProj.Domain.Business.Entities.System.Calls.Reason> GetReasonsList()
{
return GetQuery().ToList();
}
}
}
If I am not writing the full namespace the compiler consider Reason as the generated object and not as the POCO object I need.
Is there any way of preventing write the full namespace?..
You could use using aliases .. see the example 1 in http://msdn.microsoft.com/en-us/library/sf0df423(v=vs.80).aspx.
How you do it -
in your using directive do something like -
using POCOObjects = MyProj.Domain.Business.Entities.System.Calls
after that you just need to type POCOObjects.Reason
Unless your Reason class is in the MyProj.Data.EF4.EntitiesRepository.System.Calls namespace, I think you can just add using MyProj.Domain.Business.Entities.System.Calls
Otherwise you might want to check out this Q&A C#: Problem trying to resolve a class when two namespaces are similar. The workaround being that you use the global:: namespace alias. More on that here: http://msdn.microsoft.com/en-us/library/c3ay4x3d.aspx
I am having an issue trying to figure out how to appropriately name my namespace. My namespace is currently:
<CompanyName>.<ProductName>.Configuration
However, using "Configuration" conflicts with:
System.Configuration
To make matters worse, I also have a class called ConfigurationManager. I know I could change it to something like:
<CompanyName>.<ProductName>.<ProductName>Configuration
but that seems redundant. Any ideas?
EDIT: Also, I'm aware when calling either class I can fully qualify the calling code but the frequency that the classes in the System.Configuration namespace and <CompanyName>.<ProductName>.Configuration namespace will be used would make for ugly code.
EDIT2: Providing specifics:
Using statements:
using System.Configuration;
using SummitConfiguration = SST.Summit.Configuration;
Problem Line
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
Error Message
'SST.Summit.Configuration' is a 'namespace' but it is used like a 'type' (for problem line above)
Typically, in cases like this, I leave the Configuration namespace, and use an alias for accessing my namespace (instead of fully qualifying). For example:
using System.Configuration;
using PC = MyCompany.MyProduct.Configuration;
// ...
string configValue = PC.ConfigurationManager.GetValue("Foo");
What about doing something like this:
using System.Configuration;
using MyCompany.MyProduct.ProdConfig
or
using System.Configuration;
using MyCompany.MyProduct.Config
There shouldn't be a problem with using a namespace of Configuration - you'll just need to explicitly refer to the one you want by fully qualifying the name. It's a bit of a pain but I think a clear naming convention is better than coming up with a different name if the objects in your namespace really deal with configuration. As others have suggested, you can use aliases as well.
This may not work for you, but when I run into this, I just rename my namespace and/or class. Something like Config.ConfigManager.