C#: Was mache ich falsch?
Hallo, was ist an diesem Code falsch?
class Klasse
{
public string Eigenschaft;
Klasse Objekt = new Klasse
{
Objekt.Eigenschaft = "";
};
}
Als Fehler bekomme ich:
"} erwartet"
"Typ- oder Namespacedefinition oder Dateiende erwartet."
"Ungültiger Deklarator des Initialisierermembers."
"Ein Feldinitialisierer kann nicht auf das nicht statische Feld bzw. die nicht statische Methode oder Eigenschaft "Klasse.Objekt" verweisen."
Die ersten beiden Fehler kommen glaube ich daher, dass VS die Klammern falsch erkennt. Immer wenn ich Strg k; Strg d drücke, werden die Klammern ziemlich komisch verschoben. Kann man das auch irgendwie beheben?
3 Antworten
Dein Code beinhaltet sowohl einen Syntax-, als auch einen logischen Fehler.
Der Syntaxfehler liegt darin, dass du in einem Initializer kein Semikolon zum Abschluss der Zuweisung verwenden darfst (es werden ja Definitionen aufgelistet) und du nicht ein Objekt (bei dir mit dem Namen Objekt) aufschlüsseln lassen kannst, welches zu dem Zeitpunkt noch gar nicht exisitiert.
Richtig wäre also dies:
class Klasse
{
public string Eigenschaft;
Klasse Objekt = new Klasse
{
Eigenschaft = ""
};
}
Der Logikfehler wiederum wurde von DerEinsiedler bereits benannt. Würdest du versuchen, eine Instanz der Klasse anzulegen, würdest du eine Rekursion ohne Abbruch auslösen.
Und ja, es ist auch unklar, wieso eine Instanz deiner Klasse eine Instanz des selben Typs bekommen sollte. Der Vorschlag, stattdessen einen Konstruktor zu wählen, wäre da daher eher sinnig. Oder du kürzt es direkt ab:
class Klasse
{
public string Eigenschaft = "";
}
Wenn du an deinem Vorhaben festhalten möchtest, löse es beispielsweise so:
class Klasse
{
public string Eigenschaft;
public Klasse Objekt { get; set; }
}
Nach dem Anlegen der Klasse kannst du das Property setzen.
Klasse einObjekt = new Klasse();
einObjekt.Objekt = new Klasse { Eigenschaft = "" };
1) Gemeint ist das Symbol Objekt innerhalb des Initializers:
Klasse Objekt = new Klasse
{
Objekt.Eigenschaft = "";
};
Der Initializer kann nur eigene Properties und Felder aufschlüsseln. Objekt ist an dieser Stelle aber ein fremdes Objekt, welches zudem noch nicht einmal definiert wurde (es hat noch keinen Wert, der rechtsseitige Ausdruck (new Klasse ...) müsste dafür erst ausgewertet werden).
2) Klasse ist ein von dir definierter neuer (Daten-)Typ. Man kann auch Klasse dazu sagen. Du hast eine Klasse namens Klasse.
Die Frage war: Wieso musst du ein neues Objekt innerhalb der Klasse anlegen? Angenommen, deine Klasse sieht nun so aus (das Feld lasse ich hier weg, es ist gerade für die Diskussion unwichtig):
class Klasse
{
public Klasse Objekt;
}
// Main:
var einObjekt = new Klasse();
einObjekt.Objekt = new Klasse();
Dann hast du zwei Instanzen von Klasse vorliegen. Einmal einObjekt und dann innerhalb dessen noch das Feld, welches auf eine Instanz von Klasse verweist.
Das ist soweit möglich, ja. Aber es ergibt m.E. auf den ersten Blick nicht so viel Sinn.
3) Das sind Properties. Es gibt Properties, Felder und Methoden. Properties werden zwar implizit von C# zu Methoden konvertiert, doch für sich solltest du sie als eigenes sprachliches Mittel betrachten. Genaueres zu Properties kannst du in der Microsoft Dokumentation nachlesen.
2)
Die Frage war: Wieso musst du ein neues Objekt innerhalb der Klasse anlegen?
Naja, weil ich sonst einen Haufen Fehler bekommen habe. Ich dachte vielleicht muss man das so machen... Aber bei
einObjekt.Objekt = new Klasse();
warum new Klasse? Ich möchte dem doch einen String zuweisen?
3) Ach so. aber bei
Nach dem Anlegen der Klasse kannst du das Property setzen.
Da knallt's in der zweiten Zeile so richtig bei mir (ich verstehe auch nicht warum man dann new Klasse schreibt, da möchte ich doch einen Wert zuweisen und keine neue Instanz der Klasse erstellen?):
Ungültiges Token "=" in Klassen-, Struktur- oder Schnittstellenmemberdeklaration.
Ungültiges Token "=" in Klassen-, Struktur- oder Schnittstellenmemberdeklaration.
Ungültiges Token "{" in Klassen-, Struktur- oder Schnittstellenmemberdeklaration.
Ungültiges Token "{" in Klassen-, Struktur- oder Schnittstellenmemberdeklaration.
Ungültiges Token "=" in Klassen-, Struktur- oder Schnittstellenmemberdeklaration.
Ungültiges Token "=" in Klassen-, Struktur- oder Schnittstellenmemberdeklaration.
Typ- oder Namespacedefinition oder Dateiende erwartet.
Der Name "EinObjekt.Eigenschaft" ist im aktuellen Kontext nicht vorhanden.
Der Name "EinObjekt" ist im aktuellen Kontext nicht vorhanden.
Der Name "Eigenschaft" ist im aktuellen Kontext nicht vorhanden.
Der Name "Eigenschaft" ist im aktuellen Kontext nicht vorhanden.
Dann musst du für das Feld aber auch den Typ String angeben.
class Klasse
{
public string Eigenschaft;
public string Objekt; // <<< declaration as string
}
// in Main:
var einObjekt = new Klasse { Objekt = "" };
Du hast in deiner Deklaration (s.o. Fragestellung) aber den Typ Klasse angegeben.
Aus deinem Kommentar würde ich allerdings schlussfolgern, dass du eigentlich das wolltest:
class Klasse
{
public string Eigenschaft;
}
// in Main:
var einObjekt = new Klasse { Eigenschaft = "" };
Also eine Klasse mit einem String-Feld und von dieser dann eine Instanz, bei der das Feld auf eine leere Zeichenkette zeigt.
Was du bezüglich deiner Fehlermeldungen gerade konkret falsch machst, kann ich dir nicht sagen, dazu müsste ich einmal (am besten) deine komplette C#-Datei sehen (kopiere den Code in ein Pastebin, speichere dies und teile den Link hier). Anhand der Fehlermeldungen denke ich allerdings, dass du den Code irgendwo hineinkopiert hast, wo er nicht hingehört. Code-Änderungen scheint es ebenso gegeben haben. Aber wie geschrieben - teile besser deinen Code.
Aus deinem Kommentar würde ich allerdings schlussfolgern, dass du eigentlich das wolltest:
Ja, perfekt, genau das ist es! Durch ein wenig Recherche habe ich jetzt auch noch die restlichen Fehler unter Kontrolle gekriegt... Vielen Dank dass du dich da so rein gekniet hast, war mir echt eine große Hilfe!
Willst Du eine rekursive Klassendefinition machen?
Es ist nicht so ganz klar, was Du machen willst.
Aber den Konstruktor musst Du mit () aufrufen nicht mit {}
Ich würde das ca. so machen:
public class Klasse
{
public string Eigenschaft;
public Klasse()
{
Eigenschaft = "";
}
}
Ich weiß nicht was eine rekursive Klasse ist, aber ich will eigentlich nur ein Objekt von der Klasse instanziieren, und dem Objekt dann eine Eigenschaft zuweisen, die in der Klasse erzeugt wird (weiß nicht o mich das an mein Ziel bringt, aber der Gedanke ist dass ich eine Klasse habe und jedes der Objekte dieser Klasse hat eine Eigenschaft, der aber bei jedem Objekt ein anderer Wert zugewiesen wird)
Dann machst Du das am besten so.
Erst die Klassendefinition
public class Klasse
{
public string Eigenschaft { get; set; }
public Klasse()
{
Eigenschaft = "";
}
}
und dann da Wo du das Objekt der Klasse brauchst:
Klasse meineInstanzDerKlasse ;
meineInstanzDerKlasse.Eigenschafft = "Hallo";
Ok, aber die letzten zwei Zeilen generieren immer einen Haufen Fehler. Muss das dann innerhalb derselben Klasse stehen oder kann das auch direkt im Namespace stehen? (Im Namespace bekomme ich nur 5 Fehler, in einer Klasse 7)
Und was macht das
public Klasse() {}
da genau? Also was ist das?
>> aber die letzten zwei Zeilen generieren immer einen Haufen Fehler.
Naja. Die musst Du natürlich innerhalb deines Programms an einer korrekten Stelle irgendwo unterbringen.
Eben da wo Du eine Instanz der Klasse benötigst.
Das kannst du nicht einfach freifliegend in irgendeine Datei reinschreiben.
Das gehört NICHT einfach so in den Namespace und auch nicht in die Klasse selbst hinen!
Hast Du schon mal ein lauffähiges C#-Programm gehabt?
public Klasse() {}
Was das ist? Das ist ein Konstruktor für die Klasse Klasse. Darin kannst Du Code unterbringen, der für jedes Objekt der Klasse ausgeführt wird, sobald es erstellt wird.
Danke! Ich hab's jetzt...
Hast Du schon mal ein lauffähiges C#-Programm gehabt?
Tatsächlich ja, mehrere sogar... allerdings bin ich noch auf solch einem Anfängerniveau dass ich mich bisher noch nicht viel mit den Objektorientierten Aspekten beschäftigt habe...
Nein, aber man kann es benutzen ohne selbst welche zu erstellen. Sogar relativ gut. Wenn man nicht zu komplex wird kann man in Windows Forms (wo ja alles schon vorgefertigt ist, von der Klasse, bis zu den Klickevents) einfach die Mothoden, die beim Klicken oder so ausgeführt werden einfach mit Schleifen und If-Anweisungen füllen...
Ist der Code in nem Namespace drinnen?
Also:
namespace Name {
//dein Code
}
Ok wusste ich ned, programmiere noch ned lange mit c#, dachte halt wegen "Typ- oder Namespacedefinition oder Dateiende erwartet."
Danke. Das am Anfang mit dem Semikolon, das leuchtet mir ein (der erste der Fehler ist jzt. weg...), aber das danach
was genau meinst du mit aufschlüsseln? Weil mit
habe ich es ja erst erstellt, oder?
Das verstehe ich nicht... welchen Typs? Ich wollte nur ein Objekt von dieser Klasse instantiieren.
Der Code danach... benutzt man get und set nicht eigentlich bei Methoden?