Zugriffsfrage



  • Hallo,

    da ich noch recht neu in der .NET (C#) Welt bin habe ich ein kleines Verständnisproblem mit den Zugriffsmöglichkeiten von Klassen und Objekten.

    Ich habe in meinem Programm 2 Klassen. Eine davon ist die std. Klasse des Fensters. Die andere eine Klasse die das komplette "Management" meiner Sockets übernimmt. (Verbindung annehmen, Empfangen, Senden etc.pp) Von dieser wird in der Klasse des Fesnters ein Objekt angelegt. Nun kann ich über die Form also damit der Fensterklasse natürlich ohne weiteres auf das Objekt und damit die Funktionen der Socket-Klasse zugreifen, jedoch anders herum nicht. Die einzige Möglichkeit wären "static" Member der Fensterklasse die allerdings dann wiederum nicht auf Elemente der Form Zugreifen können (static->non static).

    Unter C/C++ hätte es ausgereicht den Header einzubinden um auf die Klasse zugreifen zu können. Nun wie realisiere ich es in C# das mein Objekt auf die Fensterklasse zugreifen kann? Irgendwie scheint mir da gerade eine grundlegende "Kleinigkeit" zu fehlen.

    Gruß
    S.



  • class A
    {
      public foo(){ B b = new B(); b.bar();}
    }
    
    class B
    {
    
    public bar(){ A a = new A(); a.foo();}
    }
    

    Ich verstehe das Problem nicht so recht. Zeig mal ein Beispiel.



  • In C# ist das nicht anders als in C und C++.

    Es geht immer darum, dass sich die Objekte (ich meine nicht die Klassen, die natürlich auch...) kennen.
    Das geschieht über Referenzen, Zeiger, Delegaten...

    Bsp.:

    namespace Test
    {
       class A
       {
          private B b = null;
    
          public()
          {
             b = new B(this);
          }
    
          private void tuEtwasMitB()
          {
             b.testVonB();
          }
    
          public void testVonA()
          {
             Console.WriteLine("testVonA");
          }
       }
    
       class B
       {
          private A a = null;
    
          public B(A einA)
          {
             a = einA;
          }
    
          public void tuEtwasMitA()
          {
             a.testVonA();
          }
    
          public void testVonB()
          {
             Console.WriteLine("testVonB");
          }
       }
    }
    


  • Ja jetzt wo Du es sagst weiß ich selbst nicht mehr wo mein Problem liegt. Habe gerade irgendwie nen Loop in meinem Kopf gehabt. Danke weiß nun was ich wissen wollte^^ 😉



  • Wohl doch nicht die erwartet Erleuchtung,... 😞

    Also das würde ich nicht kompiliert bekommen wenn ich die Referenz bereits im Konstruktor zuweise,
    wenn wir davon ausgehen das Class A die std. Klasse ist die beim Projekt erstellen erzeugt wird.
    (Window1 : Window).

    Ich bekomme immer seltsame Fehlermeldungen wenn ich nun in Class A ein Objekt vom Typ Class B anlege
    in der wieder rum ein Referenz Objekt auf Class A exisiert und dort eine Methode auf Form Elemente wie
    z.B. eine Edit-Box zugreift. Wenn ich Zuhause bin reiche ich den genauen Text der Meldung nach.



  • namespace WpfApplication3
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        /// 
    
        public partial class Window1 : Window
        {
            public soc SOCKET = new soc();
    
            public Window1()
            {
                InitializeComponent();
            }
    
            // UI setzten
            public void uiIncConnection()
            {
                IPAddress tmp = IPAddress.Parse(((IPEndPoint)SOCKET.sock.RemoteEndPoint).Address.ToString());
                String ip = tmp.Address.ToString();
                String port = ((IPEndPoint)SOCKET.sock.RemoteEndPoint).Port.ToString ();
                lblConnected.Content = "Connected: Yes (IP:" +ip +" Port:" +port +")";
                lblStatusListen.Content = "Listen: Off";  
            }
            // ------->
        }
    
        // Socket Klasse
        public class soc
        {
            private Window1 form;
    
            public soc()
            {
              form = new form();
            }
    
            // Status Variablen
            public bool isConnected = false;
            // --------------->
            // Socket Initialisieren
            public Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            public TcpListener listen_soc;
            // -------------------->
            // Threads
            public  Thread thWaitForConnection;
            private Thread thRecive;
            // -------------------->
            // puffer Variabeln
            String rcvPuffer;
            String prePuffer;
            int rcvLenght = 0;
            // -------------------->
            public bool socConnected = false;
    
            public int startListen( int port )
            {
                try
                {
                    listen_soc = new TcpListener(IPAddress.Any, port);
                    listen_soc.Start();
    
                    thWaitForConnection = new Thread(thWaitForConnection_M);
                    thWaitForConnection.Start();
                }
                catch
                {
                    return 0;
                }
                return 1;
            }
    
            private void thWaitForConnection_M()
            {
                Socket tmpSoc;
                tmpSoc = listen_soc.AcceptSocket();
                sock = null;
                sock = tmpSoc;
    
                // Starten des Threads zum Empfangen
                thRecive = null;
                thRecive = new Thread(thRecive_M);
                thRecive.Start();
    
                MessageBox.Show( "Eingehende Verbindung akzeptiert" );
                // UI Anpassen
                form.uiIncConnection();
    
            }
        }
    }
    

    So hatte ich es mir eigentlich gedacht. Ich bekomme es zwar so kompiliert, jedoch nach dem ich eine eingehende Verbindung bekomme und damit "form.uiIncConnection();" aufgerufen wird so tritt bei dieser Zeile "IPAddress tmp = IPAddress.Parse(((IPEndPoint)SOCKET.sock.RemoteEndPoint).Address.ToString());" der folgende Fehler auf. Ganz ehrlich bin ich da etwas ratlos.

    Ich habe die 2 Klassen mal etwas beschnitten und so gepostet das nur noch das wesentliche zu erkennen ist.

    ERROR
    NULLReferenceExeption was unhandled
    Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
    


  • 1. Rausfinden, welches Objekt denn genau null ist (mit dem Debugger)
    2. Member Variablen sollten (fast) immer private sein. Wenn nötig über get/set Methoden oder Properties den Zugriff gewähren / kontrollieren.
    3.

    private Window1 form;
    
            public soc()
            {
              //form = new form(); ?? das kompiliert doch nicht.
              form = new Window1();
            }
    

    4. Die Objekte der Klassen Window1 und soc müssen einander bekannt gemacht werden. Im aktuellen Code wird eine neues Objekt von Window1 angelegt... das darf nicht sein, wenn die miteinander komm. sollen.

    private Window1 form;
    
            public soc(Window1 f)
            {
              form = f;
            }
    
    public soc SOCKET;
    
            public Window1()
            {
                InitializeComponent();
                SOCKET = new soc(this); // hier eben DIE Instanz von Window1 übergeben.
            }
    

    Übrigens kannst Du nur vom GUI Thread auf das GUI Zugreifen. Lies mal für Control.Invoke nach.

    So, das wars vorerst mal von mir, ist nur das gröbste...

    Simon



  • *klatsch* Ja ok soweit verstanden.

    Der Witz ist ja das es sich genau darum geht auf Elemente der Form zu zugreifen.

    Werde es mir mal durchlesen. Danke.


Anmelden zum Antworten