Ich habe andere Entwickler gesehen, die statische Klassen als Namespaces verwendeten
public static class CategoryA
{
public class Item1
{
public void DoSomething() { }
}
public class Item2
{
public void DoSomething() { }
}
}
public static class CategoryB
{
public class Item3
{
public void DoSomething() { }
}
public class Item4
{
public void DoSomething() { }
}
}
Um die inneren Klassen zu instanziieren, sieht es wie folgt aus
CategoryA.Item1 item = new CategoryA.Item1();
Das Grundprinzip ist, dass Namespaces mit dem Schlüsselwort "using" ausgeblendet werden können. Bei Verwendung der statischen Klassen müssen jedoch die Klassennamen der äußeren Ebene angegeben werden, wodurch die Namespaces effektiv erhalten bleiben.
Microsoft rät in den Richtlinien davon ab . Ich persönlich denke, es wirkt sich auf die Lesbarkeit aus. Was sind deine Gedanken?
c#
c++
object-oriented
static-typing
namespace
user394128
quelle
quelle
Antworten:
Die Verwendung statischer Klassen als Namespaces widerspricht dem Zweck, Namespaces zu haben.
Der Hauptunterschied ist hier:
Wenn Sie definieren
CategoryA
,CategoryB<
wie Namespaces und wenn die Anwendung verwendet zwei Namensräume:Wenn es sich bei
CategoryA
oderCategoryB
um eine statische Klasse und nicht um einen Namespace handelt, entspricht die Verwendung für die Anwendung fast der oben beschriebenen.Wenn Sie es jedoch als Namespace definieren und die Anwendung nur 1 Namespace verwendet (ohne Berücksichtigung
CategoryB
), kann die Anwendung in diesem Fall tatsächlich Folgendes verwendenAber wenn Sie
CategoryA
eine statische Klasse definieren, ist die obige undefiniert! Man mussCategoryA.something
jedes Mal schreiben .Namespaces sollten verwendet werden, um Namenskonflikte zu vermeiden, während die Klassenhierarchie verwendet werden sollte, wenn die Klassengruppierung für das Systemmodell relevant ist.
quelle
using Item1 = CategoryA.Item1
(Ich denke, das funktioniert für verschachtelte Klassen genauso wie für Namespaces)var s = new HideMe.MyPhoneNumberIs12345678.TheRealUsefulClass()
Was hier vor sich geht, ist sicherlich kein idiomatischer C # -Code.
Vielleicht versuchen diese anderen, das Modulmuster zu implementieren - dies würde Ihnen Funktionen, Aktionen usw. sowie Klassen im 'Namespace' (dh in diesem Fall statische Klasse) ermöglichen?
quelle
Zuallererst sollte sich jede Klasse in einem Namespace befinden, damit Ihr Beispiel tatsächlich eher so aussieht:
Trotzdem sehe ich keinen Vorteil dieser Art von Code-Gymnastik, wenn man einen solchen Namensraum genauso gut definieren kann:
Wenn Sie vielleicht eines Tages darüber nachdenken, statische Methoden auf der höheren Ebene zu speichern, ist dies möglicherweise sinnvoll, entspricht aber nicht den Vorstellungen von C # -Erstellern und ist möglicherweise für andere Benutzer weniger lesbar - ich würde viel Zeit verschwenden Überlegen Sie, warum Sie dies getan haben, und überlegen Sie, ob mir eine Quelldatei fehlt, die Erklärungen liefert.
quelle
Namespaces in Java, JavaScript und .NET sind nicht vollständig und erlauben nur das Speichern von Klassen, andere Dinge wie Konstanten oder globale Methoden jedoch nicht.
Viele Entwickler verwenden die Tricks "statische Klassen" oder "statische Methoden", auch wenn einige Leute dies nicht empfehlen.
quelle
Ich weiß, dass dies eine alte Frage ist, aber ein sehr triftiger Grund, eine Klasse als Namespace zu verwenden (ein nicht statischer Grund), ist, dass C # die Definition von parametrischen oder generischen Namespaces nicht unterstützt. Ich habe zu genau diesem Thema hier einen Blogeintrag verfasst : http://tyreejackson.com/generics-net-part5-generic-namespaces/ .
Das Wesentliche dabei ist, dass bei der Verwendung von Generika zum Abstrahieren großer Mengen von Boilerplate-Code manchmal mehrere generische Parameter zwischen verwandten Klassen und Schnittstellen geteilt werden müssen. Der herkömmliche Weg, dies zu tun, besteht darin, die generischen Parameter, Einschränkungen und alles in jeder Schnittstelle und Klassensignatur neu zu definieren. Im Laufe der Zeit kann dies zu einer Zunahme von Parametern und Einschränkungen führen, ganz zu schweigen davon, dass die verwandten Typen ständig qualifiziert werden müssen, indem die Typparameter von einem Typ an die Typargumente des verwandten Typs weitergeleitet werden.
Durch die Verwendung einer äußeren generischen Klasse und das Verschachteln der zugehörigen Typen kann der Code drastisch getrocknet und seine Abstraktion vereinfacht werden. Man kann dann die parametrische Namespace-Klasse mit einer konkreten Implementierung ableiten, die alle konkreten Details liefert.
Hier ist ein triviales Beispiel:
So verwendet:
Verbrauchen Sie die Derivate wie folgt:
Der Vorteil beim Schreiben der Typen auf diese Weise liegt in der erhöhten Typensicherheit und der geringeren Umwandlung von Typen in abstrakte Klassen. Es ist das Äquivalent von
ArrayList
vsList<T>
in größerem Maßstab.quelle