Laden...

[gelöst] Klasse als Array: Der Name (Array) ist im aktuellen Kontext nicht vorhanden

Erstellt von stefanpc81 vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.130 Views
S
stefanpc81 Themenstarter:in
24 Beiträge seit 2017
vor 6 Jahren
[gelöst] Klasse als Array: Der Name (Array) ist im aktuellen Kontext nicht vorhanden

Hallo,

bevor ich mein Problem schildere, poste ich erst mal nur meinen Code, das sagt mehr aus:

in Program.cs

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());

            int ICAO_apt_gesamt = 5;
            Class_ICAO_apt[] ICAO_apt = new Class_ICAO_apt[ICAO_apt_gesamt];
            int i;
            for (i = 0; i < ICAO_apt_gesamt; i++)
            { ICAO_apt[i] = new Class_ICAO_apt(); }

            //ICAO_apt[].name = ""; ICAO_apt[].lat = ; ICAO_apt[].lon = ;
            ICAO_apt[0].name = "EDDF"; ICAO_apt[0].lat = 50.0264; ICAO_apt[0].lon = 8.5431;
            ICAO_apt[1].name = "EGLL"; ICAO_apt[1].lat = 51.4706; ICAO_apt[1].lon = -0.4619;
            ICAO_apt[2].name = "KATL"; ICAO_apt[2].lat = 33.6367; ICAO_apt[2].lon = -84.42807;
            ICAO_apt[3].name = "EGCC"; ICAO_apt[3].lat = 53.3537; ICAO_apt[3].lon = -2.27495;
            ICAO_apt[4].name = "LOWW"; ICAO_apt[4].lat = 48.1103; ICAO_apt[4].lon = 16.5697;

            
        }

In Klasse Class_ICAO_apt.cs

    public class Class_ICAO_apt
    {
        public string name;
        public double lat, lon;

    }

und in Form1.cs

        public void textBox1_TextChanged_1(object sender, EventArgs e)
        {
            string j = TextBox1.Text;
            int i;
            for (i = 0; i < ICAO_apt_gesamt; i++)
            {
                if (j==ICAO_apt[i].name)
                { ... }
            }

Es folgt für Form1.cs die Fehlermeldung> Fehlermeldung:

Der Name "ICAO_apt" ist im aktuellen Kontext nicht vorhanden

Was mache ich falsch?
Danke für Antworten.
Frohe Ostern!

2.080 Beiträge seit 2012
vor 6 Jahren

Schau dir mal an, was Scopes sind.
Kurzes Beispiel:


int a = 1;

{
    int b = 2;
    Console.WriteLine(a); // <-- funktioniert
    Console.WriteLine(b); // <-- funktioniert
    Console.WriteLine(c); // <-- funktioniert nicht
}

{
    int c = 2;
    Console.WriteLine(a); // <-- funktioniert
    Console.WriteLine(b); // <-- funktioniert nicht
    Console.WriteLine(c); // <-- funktioniert
}

Eine Variable existiert nur in ihrem Scope und in darin enthaltenen Scopes. Sobald der Programm-Ablauf den Scope verlässt, in dem sie deklariert wurde, kann die Variable nicht mehr gefunden werden.
Ein Scope kann dabei eine Methode oder z.B. eine Schleife sein. Scopes ohne Funktion (wie in meinem Beispiel) sind aber auch möglich.

Du deklarierst deine beiden ICAO-Variablen in der Main-Methode und dort kannst Du sie auch normal ansprechen, aber deine Form1-Klasse weiß davon nichts. Sie hat mit der TextChanged-Methode eine eigene Methode mit eigenem Scope, der alles, was Du in der Main-Methode tust, nicht kennt.

Du musst also dein Array an die Form1-Klasse übergeben und dir dieses Array in der Klasse merken.

PS:
Ein Scope ist meistens (nicht immer) durch geschweifte Klammern definiert. In Schleifen oder if-Statements hast Du zwar einen eigenen Scope, Du kannst aber - wenn der Inhalt nur eine Zeile ist, die Klammern weg lassen.
Lässt Du die Klammern weg, kannst Du keine Variable in diesem Scope deklarieren. Das ist in dem von mir verlinkten Artikel etwas ungünstig, denn in dem Beispiel ganz unten wird genau das gemacht.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

S
stefanpc81 Themenstarter:in
24 Beiträge seit 2017
vor 6 Jahren

Anhand des Bsp. habe ich es verstanden. Aber das macht aus meiner Sicht keinen Sinn zu Programmieren, wenn die Klassen, Variablen und Arrays nur innerhalb ihrer Klasse bzw. der .cs-Datei verfügbar zu haben.
Und womit kann ich jetzt diese Arrays "öffentlich" machen? Ich dachte immer, public und private regeln dies...
Das war ja mit Javascript in HTML deutlicher zu lösen bzw. es gab erst gar nicht solche Probleme!

16.842 Beiträge seit 2008
vor 6 Jahren

Anhand des Bsp. habe ich es verstanden. Aber das macht aus meiner Sicht keinen Sinn zu Programmieren, wenn die Klassen, Variablen und Arrays nur innerhalb ihrer Klasse bzw. der .cs-Datei verfügbar zu haben.

Im Gegenteil: es macht kein Sinn, dass alles Global ist.

Und womit kann ich jetzt diese Arrays "öffentlich" machen? Ich dachte immer, public und private regeln dies... Objektorientiertes Programmieren (C#)

Das war ja mit Javascript in HTML deutlicher zu lösen bzw. es gab erst gar nicht solche Probleme!

Nö. Auch da gibt es Scopes. (Wobei JavaScript auch eine funktionale Scriptsprache ist und nicht wirklich 100% vergleichbar mit C# ist)
Wäre ansonsten das reinste Chaos.

2.080 Beiträge seit 2012
vor 6 Jahren

Bei HTML gibt's keine Variablen und bei JavaScript hast Du das gleiche Verhalten auch.
Und das ist auch gut so, immerhin sind die meisten Programmiersprachen nicht für kleine Spaß-Programme entwickelt worden, sondern für große Anwendungen, wo im Expremfall viele Teams dran arbeiten. Was wäre das für ein Chaos, wenn man überall jede jemals deklarierte Variable sehen könnte/müsste?

Das private/public definiert die Sichtbarkeit innerhalb einer Klasse. Du kannst Eine Variable, Eigenschaft, Methode, etc. in einer Klasse deklarieren. Diese Member sind dann grundsätzlich immer in dieser Klasse sichtbar (je nachdem ob static oder nicht), die Frage ist nur, ob man die Member auch sieht, wenn man aus einer anderen Klasse versucht darauf zuzugreifen.

Und Du musst das Array als Parameter an den Konstruktor übergeben bzw. zuerst einmal braucht die Form einen Konstruktor, der diesen Parameter haben will.
Oder Du deklarierst eine Eigenschaft für dieses Array, was Du dann setzt oder eine Methode, die das entgegen nimmt, etc.

public class MyClass
{
    private int[] _myArray;

    public MyClass(int[] myArray)
    {
        _myArray = myArray;
    }

    public void DoSomething()
    {
        for (var i = 0; i < _myArray.Length; i++)
        {
            Console.WriteLine(_myArray[i]);
        }
    }
}

PS:
Ließ dir das Buch mal durch:
http://openbook.rheinwerk-verlag.de/visual_csharp_2012/
Danach dürften viele deiner Fragen sich von selbst klären 😉

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

S
stefanpc81 Themenstarter:in
24 Beiträge seit 2017
vor 6 Jahren

In der Klasse Class_ICAO_apt steht unten

bool compare = txt == ICAO_apt[a].Name;
                if (compare) { return a; }

welche mir die Fehlermeldung ausgibt, dass ICAO_apt im aktuellen Kontext vorhanden ist. Wie muss es korrekt lauten?

Kompletter Code:
in Program.cs

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());

            Class_ICAO_apt kl_apt = new Class_ICAO_apt("",0,0);
            int ICAO_apt_gesamt = kl_apt.Get_ICAO_apt_gesamt();
            Class_ICAO_apt[] ICAO_apt = new Class_ICAO_apt[ICAO_apt_gesamt];

            ICAO_apt[0] = new Class_ICAO_apt("EDDF", 50.0264, 8.5431);
            ICAO_apt[1] = new Class_ICAO_apt("EGCC", 53.3537, -2.27495);


        }

und in der Klasse

    public class Class_ICAO_apt
    {
        private int ICAO_apt_gesamt = 2;
        private string _Name;
        private double _Lat;
        private double _Lon;
        
        public Class_ICAO_apt(string Name, double Lat, double Lon)
        {
            string _Name = Name;
            double _Lat = Lat;
            double _Lon = Lon;
        }
                
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        public double Lat
        {
            get { return _Lat; }
            set { _Lat = value; }
        }

        public double Lon
        {
            get { return _Lon; }
            set { _Lon = value; }
        }

        public int Get_ICAO_apt_gesamt()
        {
            return ICAO_apt_gesamt;
        }

        public int Get_ICAO_apt_name(string txt)
        {
            for (int a = 0; a < ICAO_apt_gesamt; a++)
            {
                bool compare = txt == ICAO_apt[a].Name;
                if (compare) { return a; }
            }
            return 999;
        }

    }

Ziel ist es, durch den Vergleich von txt und von ICAO_apt[a].Name den Indexwert zu ermitteln (a). Danach will ich weiter programmieren, die entsprechenden Werte Lat und Lon des Arrays auszulesen.

5.658 Beiträge seit 2006
vor 6 Jahren

Wie muss es korrekt lauten?

Die Variable bzw. Eigenschaft muß zugreifbar sein. Das ist dir ja jetzt bereits mehrmals erklärt worden. Bitte nimm dir die Zeit, das zu verstehen und die verlinkten Artikel zu lesen. Das ist dir ja nicht umsonst gepostet worden. Und das Lesen und Verstehen können wir dir hier halt einfach nicht abnehmen.

PS: Da es sich hier um die grundlegensten Grundlagen handelt, empfehle ich auch nochmal einen Blick in [FAQ] Wie finde ich den Einstieg in C#?.

Weeks of programming can save you hours of planning

4.942 Beiträge seit 2008
vor 6 Jahren

Dein Code in der Main-Methode wird auch erst (zur Laufzeit) ausgeführt, wenn die MainForm wieder geschlossen wird (da du es nach der Application.Run-Methode geschrieben hast).

Vllt. wäre es auch besser, wenn du ersteinmal die Grundlagen anhand einer Konsolenanwendung erlernst?