Since I am using two different generic collection namespaces (System.Collections.Generic and Iesi.Collections.Generic), I have conflicts. In other parts of the project, I am using both the nunit and mstest framework, but qualify that when I call Assert I want to use the nunit version by
using Assert = NUnit.Framework.Assert;
Which works great, but I want to do the same thing with generic types. However, the following lines do not work
using ISet = System.Collections.Generic.ISet;
using ISet<> = System.Collections.Generic.ISet<>;
Does anyone know how to tell .net how to use the using statement with generics?
Unfortunately, the using directive does not do what you want. You can say:
using Frob = System.String;
and
using ListOfInts = System.Collections.Generic.List<System.Int32>;
but you cannot say
using Blob<T> = System.Collections.Generic.List<T>
or
using Blob = System.Collections.Generic.List
It's a shortcoming of the language that has never been rectified.
I think you're better off aliasing the namespaces themselves as opposed to the generic types (which I don't think is possible).
So for instance:
using S = System.Collections.Generic;
using I = Iesi.Collections.Generic;
Then for a BCL ISet<int>, for example:
S.ISet<int> integers = new S.HashSet<int>();
The only way you can alias a generic type is to specialize it as follows.
using IntSet = System.Collections.Generic.ISet<int>;
You can not alias an open generic type as you have done in your example:
using MySet = System.Collections.Generic.ISet<>;
Your alias name is the same as the class name itself, so you still have ambiguity, just as if you had a using for each namespace. Give the alias of the class a different name, i.e.:
using FirstNamespace;
using OtherObject = SecondNamespace.MyObject;
public class Foo
{
public void Bar()
{
MyObject first = new MyObject;//will be the MyObject from the first namespace
OtherObject second = new OtherObject;
}
}
In some cases you can go with inheritance:
public class MyList<T1, T2> : List<Tuple<IEnumerable<HashSet<T1>>, IComparable<T2>>> { }
public void Meth()
{
var x = new MyList<int, bool>();
}
You can alias a class doing :
using Test = NameSpace.MyClass;
Only if the class is NOT generic.
Related
I'm trying to compile a class from text at runtime. My problem is that my class uses a valueTupe in a function (AllLines), and I receive an error "C:\xxxx.cs(19,28): error CS0570: 'BaseClass.AllLines' is not supported by the language" when using this code
CodeDomProvider objCodeCompiler = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider();
CompilerParameters objCompilerParameters = new CompilerParameters();
objCompilerParameters.ReferencedAssemblies.Add("mscorlib.dll");
objCompilerParameters.ReferencedAssemblies.Add("System.IO.dll");
objCompilerParameters.ReferencedAssemblies.Add("System.Linq.dll");
CompilerResults objCompileResults = objCodeCompiler.CompileAssemblyFromFile(objCompilerParameters, filename);
EDIT:
The Textfile looks as follows :
using System;
using System.Collections.Generic;
using System.Linq;
namespace MyNamespace
{
public abstract class BaseClass
{
public List<(int LineNumber, string Value)> AllLines
{
...
}
}
}
I'm using Microsoft.CodeDom.Providers.DotNetCompilerPlatform v2.0.0.0,
Microsoft (R) Visual C# Compiler version 1.0.0.50618
Unsure if that is the actual version of roslyn.
Firstly, you were correct that you were using Roslyn as you are using Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider from the NuGet package Microsoft.CodeDom.Providers.DotNetCompilerPlatform.
However, the issue you are facing is that your text file does not contain valid C#.
Your declaration of List<T> is invalid in enclosing the type parameters in parentheses
You are adding names(?) to the type parameter declaration (LineNumber, Value).
You're providing two type parameters when List<T> only accepts one. (Maybe you meant to use a Dictionary<TKey, TValue>)
There is no body to your property declaration
Try replacing your text file with:
using System;
using System.Collections.Generic;
using System.Linq;
namespace MyNamespace
{
public abstract class BaseClass
{
public Dictionary<int, string> AllLines
{
get; set;
}
}
}
Note, you don't actually need using System or using System.Linq for this example. Also note, you don't need to use Roslyn for this. The old fashioned CodeDOM can compile it (replace Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider with Microsoft.CSharp.CSharpCodeProvider).
Where or when would one would use namespace aliasing like
using someOtherName = System.Timers.Timer;
It seems to me that it would just add more confusion to understanding the language.
That is a type alias, not a namespace alias; it is useful to disambiguate - for example, against:
using WinformTimer = System.Windows.Forms.Timer;
using ThreadingTimer = System.Threading.Timer;
(ps: thanks for the choice of Timer ;-p)
Otherwise, if you use both System.Windows.Forms.Timer and System.Timers.Timer in the same file you'd have to keep giving the full names (since Timer could be confusing).
It also plays a part with extern aliases for using types with the same fully-qualified type name from different assemblies - rare, but useful to be supported.
Actually, I can see another use: when you want quick access to a type, but don't want to use a regular using because you can't import some conflicting extension methods... a bit convoluted, but... here's an example...
namespace RealCode {
//using Foo; // can't use this - it breaks DoSomething
using Handy = Foo.Handy;
using Bar;
static class Program {
static void Main() {
Handy h = new Handy(); // prove available
string test = "abc";
test.DoSomething(); // prove available
}
}
}
namespace Foo {
static class TypeOne {
public static void DoSomething(this string value) { }
}
class Handy {}
}
namespace Bar {
static class TypeTwo {
public static void DoSomething(this string value) { }
}
}
I use it when I've got multiple namespaces with conflicting sub namespaces and/or object names you could just do something like [as an example]:
using src = Namespace1.Subspace.DataAccessObjects;
using dst = Namespace2.Subspace.DataAccessObjects;
...
src.DataObject source = new src.DataObject();
dst.DataObject destination = new dst.DataObject();
Which would otherwise have to be written:
Namespace1.Subspace.DataAccessObjects.DataObject source =
new Namespace1.Subspace.DataAccessObjects.DataObject();
Namespace2.Subspace.DataAccessObjects.DataObject dstination =
new Namespace2.Subspace.DataAccessObjects.DataObject();
It saves a ton of typing and can be used to make code a lot easier to read.
In addition to the examples mentioned, type aliases (rather than namespace aliases) can be handy when repeatedly referring to generic types:
Dictionary<string, SomeClassWithALongName> foo = new Dictionary<string, SomeClassWithALongName>();
private void DoStuff(Dictionary<string, SomeClassWithALongName> dict) {}
Versus:
using FooDict = Dictionary<string, SomeClassWithALongName>;
FooDict foo = new FooDict();
private void DoStuff(FooDict dict) {}
Brevity.
There are fringe benefits to provide clarity between namespaces which share type names, but essentially it's just sugar.
I always use it in situations like this
using Utility = MyBaseNamespace.MySubNamsepace.Utility;
where Utility would otherwise have a different context (like MyBaseNamespace.MySubNamespace.MySubSubNamespace.Utility), but I expect/prefer Utility to always point to that one particular class.
It is very useful when you have multiple classes with the same name in multiple included namespaces. For example...
namespace Something.From.SomeCompanyA {
public class Foo {
/* ... */
}
}
namespace CompanyB.Makes.ThisOne {
public class Foo {
/* ... */
}
}
You can use aliases to make the compiler happy and to make things more clear for you and others on your team:
using CompanyA = Something.From.CompanyA;
using CompanyB = CompanyB.Makes.ThisOne;
/* ... */
CompanyA.Foo f = new CompanyA.Foo();
CompanyB.Foo x = new CompanyB.Foo();
We have defined namespace aliases for all of our namespaces. This makes it very easy to see where a class comes from, e.g:
using System.Web.WebControls;
// lots of other using statements
// contains the domain model for project X
using dom = Company.ProjectX.DomainModel;
// contains common web functionality
using web = Company.Web;
// etc.
and
// User from the domain model
dom.User user = new dom.User();
// Data transfer object
dto.User user = new dto.User();
// a global helper class
utl.SomeHelper.StaticMethod();
// a hyperlink with custom functionality
// (as opposed to System.Web.Controls.HyperLink)
web.HyperLink link = new web.HyperLink();
We have defined some guidelines how the aliases must be named and everyone is using them.
I find the aliases very useful in unit testing. When you are writing unit tests, it is a common practice to declare the subject to test as
MyClass myClassUT;
being myClassUT the subject Under Test. But what if you want to write unit tests for a static class with static methods? Then you can create an alias like this:
using MyStaticClassUT = Namespace.MyStaticClass;
Then you can write your unit tests like this:
public void Test()
{
var actual = MyStaticClassUT.Method();
var expected = ...
}
and you never loose sight of what the subject under test is.
In one way it is really handy while coding in Visual Studio.
Use-case: Let's say I've to use only few classes e.g. SqlConnection from a namespace System.Data. In normal course I'll import the System.Data.SqlClient namespace at the top of the *.cs file as shown below:
using System.Data;
Now look at my intellisense. It is heavily proliferated with whole lot of classes to choose from while typing in code editor. I'm not going to use whole bunch of classes at all:
So I would rather use an alias at the top of my *.cs file and get a clear intellisense view:
using SqlDataCon = System.Data.SqlClient.SqlConnection
Now look at my intellisense view. It is super-clear and super-clean.
One reason I know; It lets you use shorter names when you have name collisions from imported namespaces.
Example:
If you declared using System.Windows.Forms; and using System.Windows.Input; in the same file when you go to access ModifierKeys you might find that the name ModifierKeys is in both the System.Windows.Forms.Control and System.Windows.Input namespaces.
So by declaring using Input = System.Windows.Input; you can then get System.Windows.Input.ModifierKeys via Input.ModifierKeys.
I'm not a C# buff but aliasing namespace seems like "best practise" to me. That way you know what you're getting and still don't have to type too much more.
You can use them to modify a code very easily.
For example:
#if USE_DOUBLES
using BNumber = System.Double;
#else
using BNumber = System.Single;
#endif
public void BNumber DoStuff(BNumber n) {
// ...
}
public void BNumber DoStuff2(BNumber n) {
// ...
}
public void BNumber DoStuff3(BNumber n) {
// ...
}
By the simple change in of the directive you can decide if your whole code works in float or double.
Just discovering Roslyn, so please be patient.
I would like to update the using directives at the top of my class to include an additional statment, for example:
using System;
public class Foo {
}
Should become:
using System;
using Custom.Bar;
public class Foo {
}
I see that I can override SyntaxRewriter and I have done this to address method level code, but I can't see an override that might give me access to these using directives?
Thanks.
Edit:
I have found this property, but I don't know how to modify it.
var tree = document.GetSyntaxTree().GetRoot() as SyntaxNode;
var compilationUnitSyntax = (CompilationUnitSyntax) (tree);
if (compilationUnitSyntax != null)
compilationUnitSyntax.Usings.Add();
Unfortunately UsingDirectiveSyntax is internal so how can I add one! :D
To create SyntaxNodes you must use the Syntax class factory methods in your case the Syntax.UsingDirective method.
And you can add a new using with the AddUsings method something like
if (compilationUnitSyntax != null)
{
var name = Syntax.QualifiedName(Syntax.IdentifierName("Custom"),
Syntax.IdentifierName("Bar"));
compilationUnitSyntax = compilationUnitSyntax
.AddUsings(Syntax.UsingDirective(name).NormalizeWhitespace());
}
Note: because of the immutability of the CompilationUnitSyntax you need to reassign your compilationUnitSyntax variable with the result of the AddUsings call.
I have a class that's name is the same as the namespace is is contained within:
Class File ReadModel.cs
namespace App.Core.ReadModel
{
public class ReadModel
{
}
}
Class File MyClass.cs
using App.Core.ReadModel; // this does not work
namespace Something
{
// using App.Core.ReadModel (Works if I un-comment)
public class MyClass
{
public void test()
{
var x = new ReadModel();
}
}
}
When trying to instantiate the class, even when trying to add a using directive at the top, the compiler is still unable to resolve the class. HOWEVER, if I put the using statements nested within the namespace, it works fine.
Can someone pls explain why this works? This is a new feature I've just discovered.
The error is: App.Core.ReadModel is a namespace but is used like a type
The difference between
using System ;
using Foo.Bar ;
namespace My.Widget.Tools
{
public class MySpecialTool
{
...
}
}
and
using System ;
namespace My.Widget.Tools
{
using Foo.Bar ;
public class MySpecialTool
{
...
}
}
is that in the first case, the directive using Foo.Bar ; causes the objects in the namespace Foo.Bar to be imported into the unnamed (global) namespace for the compilation unit. In the second case, the using directive imports the objects in the namespace Foo.Bar into the namespace My.Widget.Tools.
The difference has to do with search order in resolving unqualified references.
Unqualified references are resolved by first searching within the enclosing named namespace. If the reference is not resolved, then the unnamed (global) namespace for the compilation unit is searched.
Consider the case where the above namespace Foo.Bar contains a visible class that conflicts with a class contained in the System namespace.
In the first case, where the Foo.Bar namespace has been loading into the global namespace, you'll get an error regarding an ambiguous reference if you try to reference the conflicting object: it will search the enclosing namespace first, on not finding it, it will then look into the global namespace and find multiple objects and whine.
In the second case, the enclosing namespace is searched first, on finding an object of the desired name, the unqualified reference is resolved and the compiler is happy: no conflict.
Note that you can coerce the search order to the global namespace by qualifying an object reference with the global:: prefix. You can also define your own aliases with the using directive, either for a namespace:
using io = System.IO ;
or for a type:
using IntList = System.Collections.Generic.List<int> ;
the caveat with defining an alias for the namespace is that you then have to use the alias to resolve a reference. An alias defined for a type just gives you a [perhaps] shorthand way of naming the type. Probably more useful for generics than anything else. I don't see a lot of value in doing something like:
using Row = System.Data.DataRow ;
outside of writing obfuscated C#.
See also this question: Should 'using' statements be inside or outside the namespace?
ยง16 of ISO/IEC 23270:2006 (Information technology -- Programming languages -- C#) will tell you far more than you ever wanted to know about namespaces and using directives.
See also this MSDN piece on namespace aliases: http://msdn.microsoft.com/en-us/library/c3ay4x3d(v=vs.80).aspx
Edit again:
Nicholas answered your revised question very nicely. Please see his answer:
Visual Studio unable to resolve class name unless using nested using block
EDIT:
Using have to be at the top of the file. Move the using above the first namespace.
Example:
namespace App.Core.ReadModel
{
public class ReadModel
{
}
}
using App.Core.ReadModel; // cannot be placed here. Must be at top of file.
namespace App
{
public class Program
{
public static Main()
{
var obj = new ReadModel();
}
}
}
Original Answer (irrelevant to question):
Option 1: Rename Namespace
namespace App.Core.IO
{
public class ReadModel
{
}
}
Option 2: Use an Alias
using MyReadModel = App.Core.ReadModel.ReadModel;
public class Program
{
public static void Main()
{
var obj = new MyReadModel();
}
}
Option 3: Qualify Type Name
public class Program
{
public static void Main()
{
var obj = new App.Core.ReadModel.ReadModel();
}
}
Where or when would one would use namespace aliasing like
using someOtherName = System.Timers.Timer;
It seems to me that it would just add more confusion to understanding the language.
That is a type alias, not a namespace alias; it is useful to disambiguate - for example, against:
using WinformTimer = System.Windows.Forms.Timer;
using ThreadingTimer = System.Threading.Timer;
(ps: thanks for the choice of Timer ;-p)
Otherwise, if you use both System.Windows.Forms.Timer and System.Timers.Timer in the same file you'd have to keep giving the full names (since Timer could be confusing).
It also plays a part with extern aliases for using types with the same fully-qualified type name from different assemblies - rare, but useful to be supported.
Actually, I can see another use: when you want quick access to a type, but don't want to use a regular using because you can't import some conflicting extension methods... a bit convoluted, but... here's an example...
namespace RealCode {
//using Foo; // can't use this - it breaks DoSomething
using Handy = Foo.Handy;
using Bar;
static class Program {
static void Main() {
Handy h = new Handy(); // prove available
string test = "abc";
test.DoSomething(); // prove available
}
}
}
namespace Foo {
static class TypeOne {
public static void DoSomething(this string value) { }
}
class Handy {}
}
namespace Bar {
static class TypeTwo {
public static void DoSomething(this string value) { }
}
}
I use it when I've got multiple namespaces with conflicting sub namespaces and/or object names you could just do something like [as an example]:
using src = Namespace1.Subspace.DataAccessObjects;
using dst = Namespace2.Subspace.DataAccessObjects;
...
src.DataObject source = new src.DataObject();
dst.DataObject destination = new dst.DataObject();
Which would otherwise have to be written:
Namespace1.Subspace.DataAccessObjects.DataObject source =
new Namespace1.Subspace.DataAccessObjects.DataObject();
Namespace2.Subspace.DataAccessObjects.DataObject dstination =
new Namespace2.Subspace.DataAccessObjects.DataObject();
It saves a ton of typing and can be used to make code a lot easier to read.
In addition to the examples mentioned, type aliases (rather than namespace aliases) can be handy when repeatedly referring to generic types:
Dictionary<string, SomeClassWithALongName> foo = new Dictionary<string, SomeClassWithALongName>();
private void DoStuff(Dictionary<string, SomeClassWithALongName> dict) {}
Versus:
using FooDict = Dictionary<string, SomeClassWithALongName>;
FooDict foo = new FooDict();
private void DoStuff(FooDict dict) {}
Brevity.
There are fringe benefits to provide clarity between namespaces which share type names, but essentially it's just sugar.
I always use it in situations like this
using Utility = MyBaseNamespace.MySubNamsepace.Utility;
where Utility would otherwise have a different context (like MyBaseNamespace.MySubNamespace.MySubSubNamespace.Utility), but I expect/prefer Utility to always point to that one particular class.
It is very useful when you have multiple classes with the same name in multiple included namespaces. For example...
namespace Something.From.SomeCompanyA {
public class Foo {
/* ... */
}
}
namespace CompanyB.Makes.ThisOne {
public class Foo {
/* ... */
}
}
You can use aliases to make the compiler happy and to make things more clear for you and others on your team:
using CompanyA = Something.From.CompanyA;
using CompanyB = CompanyB.Makes.ThisOne;
/* ... */
CompanyA.Foo f = new CompanyA.Foo();
CompanyB.Foo x = new CompanyB.Foo();
We have defined namespace aliases for all of our namespaces. This makes it very easy to see where a class comes from, e.g:
using System.Web.WebControls;
// lots of other using statements
// contains the domain model for project X
using dom = Company.ProjectX.DomainModel;
// contains common web functionality
using web = Company.Web;
// etc.
and
// User from the domain model
dom.User user = new dom.User();
// Data transfer object
dto.User user = new dto.User();
// a global helper class
utl.SomeHelper.StaticMethod();
// a hyperlink with custom functionality
// (as opposed to System.Web.Controls.HyperLink)
web.HyperLink link = new web.HyperLink();
We have defined some guidelines how the aliases must be named and everyone is using them.
I find the aliases very useful in unit testing. When you are writing unit tests, it is a common practice to declare the subject to test as
MyClass myClassUT;
being myClassUT the subject Under Test. But what if you want to write unit tests for a static class with static methods? Then you can create an alias like this:
using MyStaticClassUT = Namespace.MyStaticClass;
Then you can write your unit tests like this:
public void Test()
{
var actual = MyStaticClassUT.Method();
var expected = ...
}
and you never loose sight of what the subject under test is.
In one way it is really handy while coding in Visual Studio.
Use-case: Let's say I've to use only few classes e.g. SqlConnection from a namespace System.Data. In normal course I'll import the System.Data.SqlClient namespace at the top of the *.cs file as shown below:
using System.Data;
Now look at my intellisense. It is heavily proliferated with whole lot of classes to choose from while typing in code editor. I'm not going to use whole bunch of classes at all:
So I would rather use an alias at the top of my *.cs file and get a clear intellisense view:
using SqlDataCon = System.Data.SqlClient.SqlConnection
Now look at my intellisense view. It is super-clear and super-clean.
One reason I know; It lets you use shorter names when you have name collisions from imported namespaces.
Example:
If you declared using System.Windows.Forms; and using System.Windows.Input; in the same file when you go to access ModifierKeys you might find that the name ModifierKeys is in both the System.Windows.Forms.Control and System.Windows.Input namespaces.
So by declaring using Input = System.Windows.Input; you can then get System.Windows.Input.ModifierKeys via Input.ModifierKeys.
I'm not a C# buff but aliasing namespace seems like "best practise" to me. That way you know what you're getting and still don't have to type too much more.
You can use them to modify a code very easily.
For example:
#if USE_DOUBLES
using BNumber = System.Double;
#else
using BNumber = System.Single;
#endif
public void BNumber DoStuff(BNumber n) {
// ...
}
public void BNumber DoStuff2(BNumber n) {
// ...
}
public void BNumber DoStuff3(BNumber n) {
// ...
}
By the simple change in of the directive you can decide if your whole code works in float or double.