Alias ​​d'espace de noms C # - à quoi ça sert?

96

Où et quand utiliserait-on l'alias d'espace de noms comme

 using someOtherName =  System.Timers.Timer;

Il me semble que cela ne ferait qu'ajouter à la confusion dans la compréhension de la langue.

Brad
la source
6
Que diriez-vous d'un système à l'échelle using int = System.Int32du C #? Utile, non? C'est la même utilisation qui peut être mise à profit ailleurs.
nawfal
@nawfal Je pense que les alias de type ne sont pas exportables. Cela signifie que vous ne pouvez pas définir quelque chose comme using int = System.Int32, et l'utiliser dans des endroits autres que le fichier de déclaration. Donc , ce intà Int32alias soit peut être obtenue par d'autres moyens, ou est quelque chose de spécial dans le compilateur / runtime.
KFL
1
@KFL c'est vrai, mais l'avantage que les deux offrent est de même nature.
nawfal
1
@nawfal votre argument à propos using int = System.Int32est à la fois faux et trompeur - c'est faux parce que l' intalias n'est pas implémenté de la manière que vous avez décrite. C'est trompeur parce que vous impliquez que les alias de type peuvent être utilisés globalement, tout comme comment intest utilisé Int32.
KFL
2
@KFL je n'impliquais pas les deux. Je viens de dire pourquoi avoir un nom personnalisé pour un type pourrait être utile.
nawfal

Réponses:

151

C'est un alias de type, pas un alias d'espace de noms; il est utile de lever l'ambiguïté - par exemple, contre:

using WinformTimer = System.Windows.Forms.Timer;
using ThreadingTimer = System.Threading.Timer;

(ps: merci pour le choix de Timer;-p)

Sinon, si vous utilisez les deux System.Windows.Forms.Timeret System.Timers.Timerdans le même fichier, vous devrez continuer à donner les noms complets (car cela Timerpourrait prêter à confusion).

Il joue également un rôle avec les externalias pour l'utilisation de types avec le même nom de type complet à partir de différents assemblys - rare, mais utile à prendre en charge.


En fait, je peux voir une autre utilisation: lorsque vous voulez un accès rapide à un type, mais que vous ne voulez pas utiliser un standard usingparce que vous ne pouvez pas importer des méthodes d'extension en conflit ... un peu alambiqué, mais ... voici un exemple ...

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) { }
    }
}
Marc Gravell
la source
8
Il peut être utilisé pour créer des alias d'espaces de noms ou de types de noms.
Sean Bright le
1
@Sean: oui, mais l'exemple donné était à un type
Marc Gravell
@lupefiasco: pratique de l'OP à choisir System.Timers.Timer;-p
Marc Gravell
Ah, je pensais que vous faisiez référence au concept et non à l'exemple spécifique. Mea culpa.
Sean Bright le
26

Je l'utilise lorsque j'ai plusieurs espaces de noms avec des sous-espaces de noms et / ou des noms d'objet en conflit, vous pouvez simplement faire quelque chose comme [à titre d'exemple]:

using src = Namespace1.Subspace.DataAccessObjects;
using dst = Namespace2.Subspace.DataAccessObjects;

...

src.DataObject source = new src.DataObject();
dst.DataObject destination = new dst.DataObject();

Ce qui devrait autrement être écrit:

Namespace1.Subspace.DataAccessObjects.DataObject source = 
  new Namespace1.Subspace.DataAccessObjects.DataObject();

Namespace2.Subspace.DataAccessObjects.DataObject dstination = 
  new Namespace2.Subspace.DataAccessObjects.DataObject();

Il économise une tonne de saisie et peut être utilisé pour rendre le code beaucoup plus facile à lire.

BenAlabaster
la source
17

En plus des exemples mentionnés, les alias de type (plutôt que les alias d'espace de noms) peuvent être utiles pour faire référence à plusieurs reprises à des types génériques:

Dictionary<string, SomeClassWithALongName> foo = new Dictionary<string, SomeClassWithALongName>();

private void DoStuff(Dictionary<string, SomeClassWithALongName> dict) {}

Contre:

using FooDict = Dictionary<string, SomeClassWithALongName>;

FooDict foo = new FooDict();

private void DoStuff(FooDict dict) {}
Joel Mueller
la source
8

Brièveté.

Il y a des avantages marginaux à fournir de la clarté entre les espaces de noms qui partagent des noms de types, mais essentiellement, ce n'est que du sucre.

Annakata
la source
Il montre clairement quel symbole vous utilisez. Ce n'est pas seulement du sucre, mais un peu verbeux (si vous ne voulez pas définir un nouveau nom).
Earth Engine
7

Je l'utilise toujours dans des situations comme celle-ci

using Utility = MyBaseNamespace.MySubNamsepace.Utility;

Utilityaurait autrement un contexte différent (comme MyBaseNamespace.MySubNamespace.MySubSubNamespace.Utility), mais j'attends / je préfère Utilitytoujours pointer vers cette classe particulière.

bdukes
la source
6

C'est très utile lorsque vous avez plusieurs classes avec le même nom dans plusieurs espaces de noms inclus. Par exemple...

namespace Something.From.SomeCompanyA {
    public class Foo {
        /* ... */
    }
}

namespace CompanyB.Makes.ThisOne {
    public class Foo {
        /* ... */
    }
}

Vous pouvez utiliser des alias pour rendre le compilateur heureux et rendre les choses plus claires pour vous et les autres membres de votre équipe:

using CompanyA = Something.From.CompanyA;
using CompanyB = CompanyB.Makes.ThisOne;

/* ... */

CompanyA.Foo f = new CompanyA.Foo();
CompanyB.Foo x = new CompanyB.Foo();
Sean Bright
la source
3

Nous avons défini des alias d'espace de noms pour tous nos espaces de noms. Cela permet de voir très facilement d'où vient une classe, par exemple:

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.

et

// 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(); 

Nous avons défini quelques directives sur la manière dont les alias doivent être nommés et que tout le monde les utilise.

M4N
la source
1
Ne trouvez-vous pas que souvent l'alias a plus à voir avec le contexte dans lequel il est utilisé que l'emplacement physique de l'objet?
BenAlabaster le
2

Je trouve les alias très utiles dans les tests unitaires. Lorsque vous écrivez des tests unitaires, il est courant de déclarer le sujet à tester comme

MyClass myClassUT;

étant myClassUTle sujet U nder T est. Mais que faire si vous voulez écrire des tests unitaires pour une classe statique avec des méthodes statiques? Ensuite, vous pouvez créer un alias comme celui-ci:

using MyStaticClassUT = Namespace.MyStaticClass;

Ensuite, vous pouvez écrire vos tests unitaires comme ceci:

public void Test()
{
    var actual = MyStaticClassUT.Method();
    var expected = ...
}

et vous ne perdez jamais de vue quel est le sujet à tester.

Charlie
la source
2

D'une certaine manière, c'est vraiment pratique lors du codage dans Visual Studio.

Cas d'utilisation : disons que je n'utilise que quelques classes, par exemple à SqlConnectionpartir d'un espace de noms System.Data. En temps normal, j'importerai l' System.Data.SqlClientespace de noms en haut du fichier * .cs comme indiqué ci-dessous:

using System.Data;

Maintenant, regardez mon intellisense. Il est fortement proliféré avec un grand nombre de classes parmi lesquelles choisir lors de la saisie dans l'éditeur de code. Je ne vais pas du tout utiliser tout un tas de cours:

entrez la description de l'image ici

Je préférerais donc utiliser un alias en haut de mon fichier * .cs et obtenir une vue intellisense claire:

using SqlDataCon = System.Data.SqlClient.SqlConnection

Maintenant, regardez ma vue intellisense. C'est super clair et super propre.

entrez la description de l'image ici

RBT
la source
1

Une raison que je connais; Il vous permet d'utiliser des noms plus courts lorsque vous avez des conflits de noms à partir d'espaces de noms importés. Exemple:

Si vous avez déclaré using System.Windows.Forms;et using System.Windows.Input; dans le même fichier lorsque vous accédez à l'accès, ModifierKeysvous constaterez peut-être que le nom se ModifierKeystrouve à la fois dans les espaces de noms System.Windows.Forms.Controlet System.Windows.Input. Donc , en déclarant que using Input = System.Windows.Input;vous pouvez obtenir System.Windows.Input.ModifierKeysvia Input.ModifierKeys.

Je ne suis pas un buff C # mais l'aliasing de l'espace de noms me semble être la "meilleure pratique". De cette façon, vous savez ce que vous obtenez et vous n'avez toujours pas à taper trop.

Zv_oDD
la source
1

Vous pouvez les utiliser pour modifier un code très facilement.

Par exemple:

#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) {
    // ...
}

Par le simple changement de la directive, vous pouvez décider si tout votre code fonctionne dans floatou double.

Ender Look
la source