C# Variablen Sichtbarkeit

Physically

Lt. Commander
Registriert
Nov. 2010
Beiträge
1.708
Hallo,

habe ein dummes Problem. Warum unterstreicht mir Visual Studio den markierten Text rot, mit der Meldung: "Der Name "tachoAnfangsstand" ist im aktuellem Kontext nicht vorhanden.", wobe ich doch die Variable deklariert habe.

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace KilometerRechner
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            long tachoAnfangsstand;
            long tachoEndstand;
            double gefahreneKM;
            double erstattungsSatz = 0.39;
            double erstattungsBetrag;

            InitializeComponent();
        }


        private void btnBerechnen_Click(object sender, EventArgs e)
        {
            if([COLOR="Red"]tachoAnfangsstand[/COLOR] //"tachoAnfangsstand wird hier rot unterstrichen
        }
    }
}
 
Weil du die im Konstruktor deklariert hast und nicht als globale Variable.
 
Du definierst die Variablen lokal im Constructor, nicht in der Klasse :).

Grüsse,

tolotos
 
Variablen gelten immer nur innerhalb der Klammern, in deinem Fall also im Konstruktor.
Deshalb einfach oberhalb des Konstruktors, aber innerhalb der Klasse die Variable anlegen
 
Zuletzt bearbeitet:
Und wo genau soll ich die einfügen? Wenn ich sie unter "public partial class Form1 : Form" einfügen, dann bekomme ich ein Haufen Fehlermeldungen mit "ungültiger Ausdruck "}" obwohl alles stimmt, dann noch "; erwartet" obwohl überall ein ";" ist.

EDIT: Geht doch ,sorry habe die halbe if-Verzweiung nicht gesehen, DANKE!
 
Eine Variable ist immer nur in ihrem Block gültig (Geschweifte Klammern bei C#

So gehts und das natürlich für alle Variablen, die du in anderen Methoden haben möchtest...

Außerdem solltest du im Konstruktor erst nach dem InitializeComponent() selbst Sachen machen.

PHP:
public partial class Form1 : Form
{
private long _tachoAnfangsstand;

public Form1()
{
InitializeComponent();

_tachoAnfangsstand = 0;
long tachoEndstand;
double gefahreneKM;
double erstattungsSatz = 0.39;
double erstattungsBetrag;
 
}
 
 
private void btnBerechnen_Click(object sender, EventArgs e)
{
if(_tachoAnfangsstand //"tachoAnfangsstand wird hier rot unterstrichen
}
}
 
Zuletzt bearbeitet:
Samurai76 schrieb:
Deklariere die Variable einfach als Public. K.A., wie das unter C# geht.

Ehhhh falsch Oo
Das ist wieder Sichtbarkeit, hättest du den Code angeschaut, wüsstest du, dass es nicht darum geht
 
C# ist sehr genau was Sichtbarkeit betrifft: die Grenze ist immer die nächsthöhere geschweifte Klammer. Es ist grundsätzlich alles privat, was nicht protected oder public bezeichnet wird.
Veröffentlichen kannst du nur von einer Klasse und von einer Assembly, innerhalb einer Funktion gibt es keine Zugriffsmodifizierer.
Im Unterschied zu javaScript bspw. wo die Grenze immer die Funktion { } ist, begrenzt bei C# einfach alles, auch ein if { }.

Code:
using System;
     
namespace KilometerRechner
{
    // Private Klassen
    class Beispiel0 { }
    private class Beispiel1 { }

    // Öffentliche Klasse
    public class Form1
    {

        // Privates Feld // Sieht nur diese Klasse
        // ist klein geschrieben, könnte auch ein underscore haben
        private long zahl0;

        // Protected Feld // Sehen auch abgeleitete Klassen
        protected long Zahl1;

        // Öffentliches Feld // sollte vermieden werden
        public long Zahl2;

        // Öffentliche Eigenschaft
        public long Zahl0 {
          get { return zahl0; }
          set { zahl0 = value; }
        }

        // Öffentliche Eigenschaft mit privatem Setter
        public long Zahl3 {
          get { return zahl0; }
          private set { zahl0 = value; }
        }

        // Öffentlicher Konstruktor // Es gibt auch private
        // die du aus einer statischen Factory-Funktion nutzen kannst,
        // und protected, mit denen man das Überschreiben der Klasse erzwingt
        public Form1()
        {
            long lokaleVariable = 0; // Nur in public Form1() Konstruktor sichtbar!
        }
  
        // Private Funktion   
        private void btnBerechnen_Click(object sender, EventArgs e)
        {
            // Hier siehst du zahl0, Zahl0, Zahl1, Zahl2 und Zahl3
        }

        // Protected Virtual (overridable) Funktion
        protected virtual long Rechnen() {
        }
    }
}

Übrigens werden ValueType's immer mit default Wert initialisiert, ein long mit 0, sowie Object-Types mit null. Dies ist im Gegensatz zu Variablen innerhalb einer Funktion, die du selbst wenigstens mit null initialisieren musst, da der Compiler sonst sagt, dass eine Variable verwendet wird, der nichts zugewiesen wurde.
 
Die Methode "btnBerechnen_Click" ist ein schlechtes Beispiel, da es sich hier um eine Handler-Methode des Click-Events handelt.

metadings schrieb:
Dies ist im Gegensatz zu Variablen innerhalb einer Funktion, die du selbst wenigstens mit null initialisieren musst

Man muss nicht jede Variable mit NULL initialisieren. Auch innerhalb einer Funktion nicht.

EDIT:
Auch den Vergleich mit Sichtbarkeit finde ich persönlich nicht allzu doll.
Zugriffsmodifizierer (public, internal, protected und private) haben nichts mit der (klassenweiten) Verfügbarkeit eines Klassenmembers (Private Fields, Methods) zu tun.
 
Zuletzt bearbeitet:
lbm1305 schrieb:
Die Methode "btnBerechnen_Click" ist ein schlechtes Beispiel, da es sich hier um eine Handler-Methode des Click-Events handelt.
Na und? Man kann auch EventHandler overridable machen, also protected virtual, anstatt nur private.

lbm1305 schrieb:
Man muss nicht jede Variable mit NULL initialisieren. Auch innerhalb einer Funktion nicht.
Nun statt null hätte ich default(T) sagen sollen. Grundsätzlich muss aber einer Variable etwas zugewiesen werden bevor sie verwendet wird, wobei eben nur Felder ('Variablen' einer Klasse) automatisch initialisiert werden.
Du kannst eine Variable deklarieren und sie erst später initialisieren, uninitialisiert darfst du sie aber nicht verwenden.

lbm1305 schrieb:
Auch den Vergleich mit Sichtbarkeit finde ich persönlich nicht allzu doll.
Zugriffsmodifizierer (public, internal, protected und private) haben nichts mit der (klassenweiten) Verfügbarkeit eines Klassenmembers (Private Fields, Methods) zu tun.
Unter Umständen schon, denn einen private Member siehst du in einer abgeleiteten Klasse nicht. Nur protected und public Member.

Aber um es einfach (doller) zu sagen, liegt die Sichtbarkeit einer Variable immer innerhalb der nächst höheren { } Klammern.

holy schrieb:
internal, nicht private *klugscheiß*
+1 :) internal wird aber erst interessant wenn du etwas public bezeichnest, damit ein Member nur innerhalb 'internal' einer Assembly public sein kann...
 
metadings schrieb:
Na und? Man kann auch EventHandler overridable machen, also protected virtual, anstatt nur private.

Klar, ich vererbe auch (Win)Forms.

Nun statt null hätte ich default(T) sagen sollen. Grundsätzlich muss aber einer Variable etwas zugewiesen werden bevor sie verwendet wird, wobei eben nur Felder ('Variablen' einer Klasse) automatisch initialisiert werden.
Du kannst eine Variable deklarieren und sie erst später initialisieren, uninitialisiert darfst du sie aber nicht verwenden.

Hier gebe ich Dir recht. Aber das Deutsch in dem ersten Posting war nicht allzu verständlich
 
metadings schrieb:
+1 :) internal wird aber erst interessant wenn du etwas public bezeichnest, damit ein Member nur innerhalb 'internal' einer Assembly public sein kann...

Unglaublich kompliziert ausgedrückt, aber 'ack' ;)


lbm1305 schrieb:
Klar, ich vererbe auch (Win)Forms.

Als gäbe es Events nur in Forms ^^ Es ist gänge Praxis EventHandler zu überschreiben.
 
lbm1305 schrieb:
Klar, ich vererbe auch (Win)Forms.
Ist eher selten gebe ich zu... Aber ich hatte es auch schonmal, dass die Handler durch Modellklassen bereitgestellt und daher als public bezeichnet wurden.

:freaky:

Gruß

PS: Was machst du?
Code:
public class Form1 : Form { //...
 
Zuletzt bearbeitet: (Korrektur: Wiederholungsfehler)
Soll ich jetzt noch das Fass auf machen und sagen, dass Events der absolute Graus sind und ein Programmiererleben in den Suizid treiben kann? ;-)

Ich sag nur: Jemals Memory Leaks gehabt, und sich gewundert, warum Objekte nicht von der GC eingesammelt werden? Ich sag nur Eventhandler :P
 
Erdmännchen schrieb:
Soll ich jetzt noch das Fass auf machen und sagen, dass Events der absolute Graus sind und ein Programmiererleben in den Suizid treiben kann? ;-)

Ich sag nur: Jemals Memory Leaks gehabt, und sich gewundert, warum Objekte nicht von der GC eingesammelt werden? Ich sag nur Eventhandler :P

Das liegt aber nicht an den Events, sondern an der "Unfähigkeit" des Entwicklers. Ist nicht allzu schwer das Event wieder abzubestellen :D
 
Zurück
Oben