Namespaces
-
Hallo,
ich habe gerade ein Problem mit C# Namespaces, das ich mir nicht erklären kann, vielleicht kann mich hier jemand erleuchten. Wir benutzen die DevExpress WPF Suite, deren Klassen teilweise im Namespace
DevExpress.Xpf
liegen. Jetzt habe ich mir ein paar Erweiterungsmethoden gebaut und die im NamespaceABC.DevExpress.Xpf.Extensions
implementiert. Solange ich die .cs Datei direkt in´s Projekt einbinde gibt´s da auch kein Problem, aber wenn ich die Extension als DLL baue bekomme ich die Fehlermeldung
"Der Namespace Xpf kann nicht im Namespace ABC.DevExpress gefunden werden."
Was mich arg wundert, denn in meiner Erweiterungs-DLL wird die entsprechende DevExpress-DLL, in der die Xpf-Komponenten leben, referenziert. Damit ist im DLL-Projekt der NamespaceDevExpress.Xpf
bekannt. Es sieht aber so aus, als würde der Compiler nur imABC.DevExpress
Namespace nach demXpf
Namespace suchen, und nicht im NamespaceDevExpress
.Kann mir das jemand erklären?
-
Was für ein Namespace soll bei dir
ABC
sein? Ist das euer eigener?Dann solltest du stattdessen direkt
DevExpress.Xpf.Extensions
benutzen (ohneABC.
!).Wenn du nämlich
using DevExpress.Xpf
benutzt, gibt es eine Mehrdeutigkeit und es würde, wie von dir schon beschrieben, nurABC.DevExpress.Xpf
benutzt und nichtDevExpress.Xpf
.Du könntest zwar mittels
global::DevExpress.Xpf
oder einem eigenemusing
-Alias auch auf letzteren zugreifen, aber das halte ich für zu kompliziert und fehleranfällig.
-
Danke für die Antwort.
Ja,
ABC
ist unser eigener Namespace. Find´s komisch, dass der Compiler die Mehrdeutigkeit nicht bemängelt und das Problem nur dann auftritt, wenn die Erweiterungen in einer eigenen DLL liegen.
Mir fehlen da auch die Best Practices im Umgang mit Namespaces, sollte man Erweiterungsmethoden dann auch nur in dem Namespace implementieren, in dem auch die erweiterte Klasse liegt?
-
Mehrdeutigkeit nur aus Sicht des Entwicklers, für den Compiler sind die Prioritäten klar: erst im (Sub-)Namespace der aktuellen Klasse suchen und danach erst im globalen.
Und Erweiterungsmethoden werden ja üblicherweise von den Entwicklern der Klasse selbst angeboten und daher im gleichen Namespace (bzw. Subnamespace) implementiert.
Außerdem fällt mir noch ein, daß es einen Unterschied gibt, wo man die
using
-Deklarationen hinschreibt:using XYZ; namespace ABC { }
oder
namespace ABC { using XYZ; }
Bei ersterem bezieht sich XYZ auf den globalen Namespace, beim zweitem wird zuerst geschaut, ob es innerhalb des aktuellen Namespace (hier also
ABC
) einen Subnamespace gibt (also 'ABC.XYZ`) und nur, wenn er nicht existiert wird der globale genommen.
-
@Th69
Ja eben nicht. Es gibt die beiden NamespacesABC.DevExpress
undDevExpress
(absolute Namen). Der Compiler findet irgendwann die Direktiveusing DevExpress.Xpf
(glaube ich) und sucht nur inABC.DevExpress
und nicht inglobal::DevExpress
, in demXpf
tatsächlich liegt.
Meine Fehlermeldungen kommen aus einer XAML-Datei, in denen Aliase für einzelne Namespaces vergeben werden. Der relevanter Alias wird durch den Inhalt einer Datei erzeugt, die durch eine URL (xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core") benannt wird. Leider kann ich in diese Datei nicht reingucken, vllt steht da ja auch sowas drin:using namespace DevExpress; using namespace Xpf; // meint DevExpress.Xpf
und dann verhaspelt sich der Compiler.
Dasglobal::
davorzuschreiben scheidet aus, weil der Fehler in einer automatisch generierten .g.cs Datei kommt, die automatisch aus einer XAML Datei erzeugt wird.
-
Davorschreiben kannst du vielleicht nichts, aber reingucken solltest du können.
Und wasusing MyNamespace;
in C# angeht: AFAIK kann man da sowieso nur absolute Bezeichner angeben. Ich hab das zumindest noch nie so gesehen wie du es geschrieben hast.Ansonsten... hast du mal den Default Namespace des Projekts überprüft? Ist der gleich wie beim anderen Projekt wo es funktioniert?
-
@hustbaer sagte in Namespaces:
Ansonsten... hast du mal den Default Namespace des Projekts überprüft? Ist der gleich wie beim anderen Projekt wo es funktioniert?
Nein, guter Punkt, das könnte ich mir mal angucken. Wobei der aber eigentlich auch keine Rollen spielen sollte, wenn die
using
Direktiven immer den absoluten Namespace-Namen benutzen.
-
@hustbaer: Schau dir mein zweites Beispiel an. Dies benutze ich selber in meinen eigenen Projekten sehr oft, damit ich für Zugriff auf die Sub-Namespaces nicht immer wieder den eigenen Main-Namespace angeben muß.
Afaik verwenden aber die Code-Generatoren immer die erste Schreibweise mit voll ausgeschriebenen Namespace.