Eine Frage zu Scopes in C#
-
Zunächst: Ich komme eigentlich von C/ C++ und daher sind mir nicht unbedingt alle Konzepte von C# gleichermassen vertraut. Zum Beispiel finde ich es nach wie vor irritierend, dass es keine Includes gibt, was dann auch zu dieser Frage hier führt.
Ich schreibe eine Windows Anwendung, daher wird vom VS die Datei "Form1.cs" bekanntlich automatisch erzeugt. Füge ich einem Steuerelement dieses Formulars per Doppelklick neue Funktionen hinzu, werden sie in dieser Datei gecoded.
Wenn ich jetzt in dieser Datei z.B. ein DataSet ansprechen will (welches ich über den Datenquellenassistenten hinzugefügt habe), kann ich das in der "Form.cs" Datei benutzen, alle Member dieses DataSet sind bekannt, der ConnectionString kann verwandt werrden, ohne ihn neu schreiben zu müssen...alles Prima.
Wenn ich nun der Übersicht halber Funktionalitäten in andere Klassen auslagern will (Hinzufügen-> Neue Klasse) wird dem Projekt eine neue *.cs Datei hinzugefügt, Member dieser Klasse sind vom Gleichen Namespace wie "Form1.cs" und in der Regel ist dies der Projektname.
Ich kann so auch die Objekte anderer, dem Projekt( -namespace) zugehöriger Klassen nutzen, Ihre Member etc.
Will ich hingegen in einer solchen *.cs File Das Dataset nutzen, so steht es mir nur eingschränkt zur Verfügung, nicht alle Memeber sind bekannt, mein Connection String ebenfalls nicht...in der Form1.cs Klasse sind sie es hingegen schon. Warum? Und wie gebe ich dies auch den anderen Klassen bekannt? Includes gibt es nicht, "friend" auch nicht...?
-
Das hat mit includes und Dateien erstmal gar nichts zu tun, sondern nur mit Sichtbarkeit. Du musst dir eigentlich nur mal den Code ansehen, den der GUI-Designer generiert. Der sieht dann so aus:
class Form1 { [...] private Button myButton; private DataSet myDataSet; [...] }
Und jetzt ist auch völlig klar, warum das DataSet nur innerhalb der Klasse Form1 zur Verfügung steht.
-
Eben nicht. die Methoden fuer die Buttons etc. sind private. Das DataSet ist nichteinmal in dieser Klasse deklariert.
-
ja wie Optimizer schon sagte einfach mal den generierten Code in bequemer zurückgelehnter Haltung angugcken.
Harte lösung für Klassenmember:
-------------------------------
Zur Not dann von den Membern die man woanders braucht private ---> zu public
ändern. Ich weiss die gefällt nicht wgen Geheinisprinzipverstoss, aber was solls zum "schnellen Testen"!Bessere Lösungen hinzufügen von Neuen oder vorhanden Elmenten:
Ausgangspunkt ein Formular was in anderen Instanzen/Klassen/Objekten nutzbar sein soll!
Spendier Deinem Hauptformular eine Selbstgebastelte-Property.
Das können die zusätzlichen Klassen dann nutzen indem Du diesen über Ihren Konstruktor eine Instanz Deines HauptFormular gibst.// Beispiel eines Hauptformular wild aus meine Wust aus Projekten genommen namespace OpwWirtschaft { public class Form1 : System.Windows.Forms.Form { private DataSet ds = null; // Das brauche ich auch woanders public DataSet Datenquelle { get { return ds; } } } }
1. Bei Neuen Elementen ist das so:
----------------------------------
So wenn Du jetzt in der IDE z.B über den Projektexplorer
ein neues Element hinzufügst wird eine Datei generiert Endung .cs
diese bekommt durch den Codegenerator gleich denselben Namensraum wie dein
Hauptprojekt in dem Fall OpwWirtschaft
Dort in der Datei hast Du dann Deine Klasse dort änderst Du dann den automatisch gecodet Konstruktor ab oder machst eine zweiten rein Der als Übergabeparameter
Dein Hauptformular bekommt. Ist soweit in C++ auch nicht weiter wild und sollteeinem gleich bekannt vorkommen.hinzugefügte wird dadurch .cs-File, mit Namensraum der Hauptquellcodedatei deines Projektes, wie Du selbst ja auch schon festgestellt hast!
zumeist sieht man im Projektexplorer dann eine neue Datei mit dem Namen Class1.csnamespace OpwWirtschaft { public Class1 { // Konstruktur vom Codegenerator den Du con seiner Signatur abändern kannst public Class1() { } private DataSet ichwillDasDataSetAusForm1; public Class1(Form1 form1) { ichwillDasDataSetAusForm1 = form1.Datenquelle; } } }
2.Oder man fügt schon bestehende Objekte/Resourcen auch Assembly genannt ins Projekt ein:
---------------------------------------------------------------------------
über den Projektexplorer --> Kontextmenü ---> "Verweis hinzufügen"
hast Du bestimmt schon gesehenDurch diesen Vorgang bekommst Du im Objektexplorer den eigeladen
Namensraum mit seinem Inhalt angezeigt. Kannst es ohne ein using gemacht zu haben im Code aber noch nicht nutzen.Um vorhanden Komponeten,Bibliotheken etc zu nutzen also so vorgehen
1. über den Projektexplorer --> Kontextmenü ---> "Verweis hinzufügen"
2. Komponete zugänglich machen in dem ein using auf den Namensraum
der hinzugefügten Resource/Assembly gemacht wirdD.h in einem anderen Projekt würde ich ein Verweis aufnehmen
Wenn dürftige Doku zu diesem Assembly vorhanden ist gucke ich in den
"Objektexplorer" der IDE, weil dann kenne ich den Namen der Namensräume.
Das ermöglicht mir dann in meinem Projekt am Anfang ein using zu machen
um es wirklich auch nutzen zu können.using Namensraum.Den.ich.über.DenObjektexplorerInErfahrungBringen.Konnte.über.die.externe.Resource;
In jeder Klasse des Projektes wo ich die eingebundene Resource nutzen will muss
ein entsprechendes using auf den Namensraum die diese Resource mitbringt existieren.hmm ich hoffe ich konnte mich mit Händen und Füssen irgenwie gut ausdrücken
-
muss mich korrigieren
nicht Objektexplorer sondern heisst Objektbrowser
-
Guckmal nach wenn Du dei Datenbankverbindung per Assitent gemacht hast und das DataSet über eine Datenbankadapter per rechtsklick auf diesen im Formulardesigner gemacht hast wird dieses DataSet an den Namensraum deines Projektes gebunden.
mein Projektnamensraum heisst ja OpwWirtschaft
deshalb wurde vom Quellcodegenerator bei mir das Ding so
deklariertprivate OpwWirtschaft.DataSet1 dataSet11;
bei Dir müsste
esprivate SarumansNamensraum.DataSet1 dataSet11;
heissen im Hauptformular deines Projektes.
-
Such in der Quellcodedatei Deines Hauptformular wieder
per STRG+F und gib als Suchzeichenkette den Namen der Instanz
des DataSet ein, die solltest Du ja kennen.Dann müsstes Du auch über die Deklaration stossen.
Dann ein Property in die Klassendefinition rein
vom Typ der Instanz Deines gefunden DataSet.// im Hauptformularklasse definierte Property public DataSet Datenquelle { get { return this.DataSetInstanzvariable; } }
Willst Du nun in anderen Klassen dieses DataSet nutzen
parametrisieren deren Konstruktur oder deren Methoden mit eine Variablen vom Typ
Deiner Hauptformularinstanz.
Dann kannst Du im Konstruktor oder den Methoden von der Parametervariablen
die Eigenschaft/Property "Datenquelle" nutzen.
-
Alles was im Entwurfsmodus per Drag and Drop aus der Toolbox aufs Formular gezogen wird.
Auch das was im Projektmappenexplorer hinzugefügt wurde
müsste man im Objektbrowser der IDE wiederfinden!
Im Tree-View des Objektbrowser dann einfach den Projektnamensraum der als
Baumknoten sichtbar ist aufklappen.P.S.: Objektbrowser ist z.B. auch dann sehr nützlich wenn man Verweise
auf alte COM- und ActiveX-Steuerelemente ins Projekt aufnimmt.
-
Objektbrowser
Projektexploerer == Projektmappen-ExploererErreichbar indem du das Menü "Ansicht" obere Leiste aufklappst.
-
Danke für die ausführliche Antwort!! Hast echt geholfen.