Entwickler-Ecke

C# - Die Sprache - Operatoren Überladen


ThE_JaCk - So 24.04.11 00:00
Titel: Operatoren Überladen
Hallo Leute,

ich hab da ein Problem und hoffe ihr könnt mir dabei helfen. Der folgende Quelltext ist mir gegeben:



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
class ValueSet<T>
{
  private T[] values;
  private int capacity;
  private int count;
  // hier die erforderlichen Definitionen
  

}

class Program
{
  static void Main(string[] args)
  {
    ValueSet<int> V1 = new ValueSet<int>(100);
    ValueSet<int> V2 = new ValueSet<int>(100);
    V1 = V1 + 1 + 3 + 6;
    V2 = V2 + 4 + 3 + 7 + 6;
    ValueSet<int>.Print(V1); // 1 3 6
    ValueSet<int>.Print(V2); // 4 3 7 6
  }
}


Um das zu bewerkstelligen hab ich erstmal einen Konstruktor angefertigt (unter //hier die erforderlichen Definitionen):



C#-Quelltext
1:
2:
3:
4:
5:
    public ValueSet (int capacity)
        {
            this.capacity = capacity;
            this.values = new object[capacity];
        }


Dann wollte ich den + Operator überladen mit:



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
    public static ValueSet operator +(ValueSet obj, int zahl)
        {
            for (int i = 0; i < count; i++)
            if (obj.values[i] == zahl) return false
            obj.values[count] = value;
            obj.count++;
            return obj;
        }


Mein Problem ist aber, dass ich ständig die Fehlermedlung "Einer der Parameter eines binären Operators muss der enthaltende Typ sein." bekomme.
Was ich aber komisch finde, denn einer der Parameter ist doch von diesem Typ. Was muss ich anders machen :? ?

P.S.:Die Print funktion ist mir erstmal nicht so wichtig.


Kha - So 24.04.11 00:31

:welcome: in der EE!

user profile iconThE_JaCk hat folgendes geschrieben Zum zitierten Posting springen:
Was ich aber komisch finde, denn einer der Parameter ist doch von diesem Typ.
Nein, von einem anscheinend gleichnamigen, aber untypisierten Typ. Du hast den Typparameter <T> vergessen, genauso beim Rückgabetyp.

PS: Es gibt einen impliziten Cast von bool nach ValueSet<T> :shock: ?


ThE_JaCk - So 24.04.11 09:57

Moin Moin, danke erstmal für die Antwort :D

Sry, da ich gerade erst angefangen habe mit C# weiß ich nicht so genau was du meinst mit

Zitat:
Nein, von einem anscheinend gleichnamigen, aber untypisierten Typ. Du hast den Typparameter <T> vergessen, genauso beim Rückgabetyp.


Ich denke mal du meinst das evtl so:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
    public static ValueSet<intoperator +(ValueSet<int> obj, int zahl)
        {
            for (int i = 0; i < count; i++)
            if (obj.values[i] == zahl) return false
            obj.values[count] = value;
            obj.count++;
            return obj;
        }


oder so:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
    public static T operator +(T obj, int zahl)
        {
            for (int i = 0; i < count; i++)
            if (obj.values[i] == zahl) return false
            obj.values[count] = value;
            obj.count++;
            return obj;
        }


aber falls eines davon richtig ist, wie mache ich das dann mit dem Rückgabetyp :?:

Und woher kommt die Frage

Zitat:
PS: Es gibt einen impliziten Cast von bool nach ValueSet<T> :shock: ?


Ich habe doch nirgendwo gecastet und wo siehst du bool? Sry wie gesagt bin anfänger :roll:


Th69 - So 24.04.11 10:55

Hallo,

weder noch ;-)

Richtig ist:

C#-Quelltext
1:
2:
3:
4:
public static ValueSet<T> operator +(ValueSet<T> obj, T zahl)
{
  // ...
}


Und bei

C#-Quelltext
1:
    if (obj.values[i] == zahl) return false;                    

gibst du ja einen boolschen Wert zurück (und das ergibt eben keinen Sinn, denn der Operator soll ja ein ValueSet<T> zurückgeben - also "return obj").

Du scheinst noch nicht verstanden zu haben, daß das 'T' einfach nur ein Platzhalter für einen beliebigen Datentypen ist, d.h. wenn du dann ValueSet<int> verwendest entspricht das 'T' dann einfach 'int'.
Und daher mußt du deine generische Klasse eben so schreiben, daß du anstatt eines konkreten Datentypen 'T' schreiben mußt (den Rest erledigt dann der Compiler ;-))

P.S. Zwei weitere Fehler hast du noch in deiner Methode - aber die findest du dann sicherlich alleine raus (bedenke, daß die Operator-Methode als 'static' deklariert ist!)


ThE_JaCk - So 24.04.11 13:35

Heyho Leute, ihr seid die größten :!: :D

Habs endlich zum laufen gebracht dank eurer Hilfe. Achso und wegen dem bool Rückgabetyp... hatte ich leider ganz übersehen :oops:

Und hier nochmal der gesamte Code :) :


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:
42:
43:
44:
45:
46:
    class ValueSet<T>
    {
        private T[] values;
        private int capacity;
        private int count;
        // hier die erforderlichen Definitionen

        public ValueSet (int capacity)
        {
            this.capacity = capacity;
            this.values = new T[capacity];
        }

        public static ValueSet<T> operator +(ValueSet<T> obj, T zahl)
        {

            for (int i = 0; i < obj.count; i++)
              if (obj.values[i].Equals(zahl)) return obj;  
            obj.values[obj.count] = zahl;
            obj.count++;
            return obj;   
        }


        public static void Print(ValueSet<T> obj)
        {
            for (int i = 0; i < obj.count; i++)
                Console.Write("{0} ", obj.values[i]);
            Console.WriteLine();
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            ValueSet<int> V1 = new ValueSet<int>(100);
            ValueSet<int> V2 = new ValueSet<int>(100);
            V1 = V1 + 1 + 3 + 6;
            V2 = V2 + 4 + 3 + 7 + 6;
            ValueSet<int>.Print(V1); // 1 3 6
            ValueSet<int>.Print(V2); // 4 3 7 6
        }
    }
}


Falls euch noch irgendwas auffällt, bidde sagen! Danke