Autor Beitrag
duckhunter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mi 26.09.07 17:34 
Hi Leute,

ich habe vor von VB auf C# umzusteigen. Allerdings habe ich schon ein Problem.

Ich habe eine Root-Klasse. In dieser Root-Klasse befinden sich mehrere "Unterklassen". Ich mochte aber von diesen Unterklassen auf die Eigenschaften der Root-Klasse zugreifen und diese auch verändern können. In VB ging das so.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
Module Module1

    Sub Main()
        Dim _Root As New Root()
        Console.ReadKey()
    End Sub

    Private Class Root

        Dim _i As Integer
        Dim _Unterklasse As Unterklasse

        Public Sub New()
            _i = 5
            Console.WriteLine(_i.ToString())
            _Unterklasse = New Unterklasse(Me)
            Console.WriteLine(_i.ToString())
        End Sub

        Private Class Unterklasse

            Public Sub New(ByRef RootKlasse As Root)
                RootKlasse._i = 10
            End Sub

        End Class

    End Class

End Module


Hier klappt alles wunderbar. Die Variable _i hat zuerst den Wert 5, dann wird sie über die andere Klasse geändert und hat den Wert 10. Nun das gleiche in C#.

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Root _Root = new Root();
            Console.ReadKey();
        }

        private class Root
        {
            int _i;
            Unterklasse _Unterklasse;

            public Root()
            {
                _i = 5;
                Console.WriteLine(_i.ToString());
                _Unterklasse = new Unterklasse(ref this);
                Console.WriteLine(_i.ToString());
            }

            private class Unterklasse
            {
                public Unterklasse(ref Root RootKlasse)
                {
                    RootKlasse._i = 10;
                }
            }
        }
    }
}


Hier kommt dann der Fehler:
"<this>" kann nicht als ref- oder out-Argument übergeben werden, da das Element schreibgeschützt ist.


Kann ich das irgendwie umgehen oder gibt es vielleicht sogar eine ellegantere Lösung für das Problem?

mfg und vielen Dank im Voraus
duckhunter
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 26.09.07 19:24 
VB kompiliert das? Lol[1].
Eine Übergabe by reference ist hier jedenfalls unnötig, da du der Variablen selbst nichts zuweist, nur eine Eigenschaft änderst. Den ref-Modifier solltest du also einfach so entfernen können.
Noch ein paar Tipps:
  • Unterstriche sind böse. Felder- und Parameternamen werden normalerweise mit einem kleinen Buchstaben begonnen.
  • Die zwei privates kannst du weglassen, ist bereits der Standard-Modifier für alle Member innerhalb eines Typs.
  • Auch wenn - oder gerade weil - das wohl nur ein Beispielcode ist: Nested Types werden äußerst selten benutzt. Sicher, dass du dann auch noch zwei ineinander verschachtelte brauchst ;) ?


[1]Nein, mehr fällt mir dazu wirklich nicht ein.
duckhunter Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mi 26.09.07 19:46 
Hmm das versteh ich jetzt nicht ganz, wie sollte ich dann auf die Root-Klasse zugreifen, wenn in dieser was geändert werden muss?

danke für die Hilfe!!

mfg
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 26.09.07 19:50 
Wenn meine Erklärung nix taugt, klau ich eben eine aus dem SDK :-B :
Passing Reference-Type Parameters (C# Programming Guide) hat folgendes geschrieben:
A variable of a reference type does not contain its data directly; it contains a reference to its data. When you pass a reference-type parameter by value, it is possible to change the data pointed to by the reference, such as the value of a class member. However, you cannot change the value of the reference itself; that is, you cannot use the same reference to allocate memory for a new class and have it persist outside the block. To do that, pass the parameter using the ref or out keyword.
duckhunter Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mi 26.09.07 20:15 
Hmmm ... jetzt hab ich alles verstanden *gggg*.

Sorry steh im Moment voll auf der Leitung, kannst du das vllt in einen Source Code oder als Beispiel anführen?

Danke ;)

mfg
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 26.09.07 20:54 
Noch einmal: Entferne einfach die zwei ref und dein Programm wird funktionieren.
duckhunter Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mi 26.09.07 21:04 
Ahh sehr gut danke.

Aber warum funktioniert es in diesem Fall?

Wenn ich z.B. folgenden Programmcode habe:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
using System;
using System.Collections.Generic;
using System.Text;


namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Root _Root = new Root();
            Console.ReadKey();
        }


        private class Root
        {
            int _i;
            Unterklasse _Unterklasse;


            public Root()
            {
                _i = 5;
                Console.WriteLine(_i.ToString());
                _Unterklasse = new Unterklasse(_i);
                Console.WriteLine(_i.ToString());
            }


            private class Unterklasse
            {
                public Unterklasse(int i)
                {
                    i = 10;
                }
            }
        }
    }
}


Wenn ich das so programmiere, dann wird i natürlich nicht 10, außer ich übergebe es so:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
            public Root()
            {
                _i = 5;
                Console.WriteLine(_i.ToString());
                _Unterklasse = new Unterklasse(ref _i);
                Console.WriteLine(_i.ToString());
            }


            private class Unterklasse
            {
                public Unterklasse(ref int i)
                {
                    i = 10;
                }
            }


Warum wird nun die Variable i in der Klasse (ohne der ref-Übergabe) geändert und warum wird i nicht geändert, wenn ich nur die Variable (wie im Codeblock 1) übergebe. Wenn ich mit i mit ref Übergebe (Codeblock 2) funktioniert es logischerweise.

mfg

Edit:
Sry war mein Fehler, jetzt ist alles klar.... Ich habe hier ja nur ein schnelles Beispiel angegeben, was ich in Wirklichkeit für was komplexeres benötige... Naja egal auf jeden Fall jetzt klappt alles, danke nochmal Khabarakh!