2009-11-06 12 views
7

Cosa c'è di sbagliato in questo codice C#? Ho provato a sovraccaricare l'operatore + per aggiungere due array, ma ho ricevuto un messaggio di errore nel modo seguente:Sovraccarico dell'operatore + per aggiungere due array

Uno dei parametri di un operatore binario deve essere il tipo contenente.

class Program 
{ 
    public static void Main(string[] args) 
    { 
     const int n = 5; 

     int[] a = new int[n] { 1, 2, 3, 4, 5 }; 
     int[] b = new int[n] { 5, 4, 3, 2, 1 }; 
     int[] c = new int[n]; 

     // c = Add(a, b); 
     c = a + b; 

     for (int i = 0; i < c.Length; i++) 
     { 
     Console.Write("{0} ", c[i]); 
     } 

     Console.WriteLine(); 
    } 

    public static int[] operator+(int[] x, int[] y) 
    // public static int[] Add(int[] x, int[] y) 
    { 
     int[] z = new int[x.Length]; 

     for (int i = 0; i < x.Length; i++) 
     { 
     z[i] = x[i] + y[i]; 
     } 

     return (z); 
    } 
} 
+0

La pagina dell'esercitazione MSDN su sovraccarico ha più informazioni - http://msdn.microsoft.com/en-us/library/aa288467%28VS.71%29.aspx – ChrisF

+0

Stiamo considerando l'aggiunta di "operatori di estensione" a un ipotetico versione futura di C#, che potrebbe risolvere il tuo problema. Sondaggio Straw: qualcuno di voi ha scenari IMPRESSIONARI per questa funzione? Più fantastici scenari REALISTICI possiamo ottenere, più è probabile che una caratteristica venga implementata un giorno. Mandali a modo mio; puoi usare il link email sul mio blog. –

+0

Grazie Eric.Significa che otterremo anche "Extension Everything" :) –

risposta

16

Gli operatori devono essere dichiarati all'interno di un corpo di "classe correlata". Per esempio:

public class Foo 
{ 
    int X; 

    // Legal 
    public static int operator+(int x, Foo y); 

    // This is not 
    public static int operator+(int x, int y); 
} 

Dal momento che non si ha accesso alla realizzazione di array, la soluzione migliore potrebbe essere quella di uno avvolgere gli array in una propria implementazione in modo da poter fornire altre operazioni (e questo è l'unico modo . per rendere l'operatore + lavoro

D'altra parte, è possibile definire un metodo di estensione del tipo:

public static class ArrayHelper 
{ 
    public static int[] Add(this int[] x, int[] y) { ... } 
} 

la volontà ancora portare a chiamate naturali (x.Add(y)) evitando di avvolgere gli array nella propria classe.

1

Quando si vuole sovraccaricare le + operatore tra tipo AA e BB, è necessario farlo in AA classe o BB e non in una classe denominata programma (come hai fatto).

Sfortunatamente, si non è possibile scrivere codice nella classe Array.

Che cosa si può fare è quello di

  • creare una classe che implementa IList
  • e mettere l'operatore + in quella classe.

Se è necessaria un'implementazione più dettagliata, basta chiedere a me.

+0

E 'un peccato che non ci sia modo in cui una classe può implementare "this [int]" in modo tale da far corrispondere il comportamento di un subscripting di array (restituendo un 'byref' piuttosto che un valore). – supercat

2

Lo stato indica che uno dei parametri per l'operatore deve essere dello stesso tipo di quello della funzione di operatore. Quindi se la funzione operatore è un membro di MyClass su dei parametri deve essere di tipo MyClass.

class MyClass 
{ 
... 

public static int[] operator+(MyClass x, int[] y) 
    // public static int[] Add(int[] x, int[] y) 
    { 
     int[] z = new int[x.Length]; 

     for (int i = 0; i < x.Length; i++) 
     { 
     z[i] = x[i] + y[i]; 
     } 

     return (z); 
    } 
} 
1

È possibile aggiungere operatori solo a un tipo creato dall'utente. A int[] è un tipo integrato in cui non è possibile aggiungere operatori.

È possibile creare la propria classe che incapsula un array e aggiungervi l'operatore.

2

si può usare qualcosa di simile:

class Program { 
    static void Main(string[] args) { 
    const int n = 5; 

    var a = new int[n] { 1, 2, 3, 4, 5 }.WithOperators(); 
    var b = new int[n] { 5, 4, 3, 2, 1 }; 

    int[] c = a + b; 

    for (int i = 0; i < c.Length; i++) { 
     Console.Write("{0} ", c[i]); 
    } 

    Console.WriteLine(); 
    } 
} 

public static class Int32ArrayExtensions { 
    public static Int32ArrayWithOperators WithOperators(this int[] self) { 
    return self; 
    } 
} 

public class Int32ArrayWithOperators { 
    int[] _array; 

    public Int32ArrayWithOperators(int[] array) { 
    if (array == null) throw new ArgumentNullException("array"); 
    _array = array; 
    } 

    public static implicit operator Int32ArrayWithOperators(int[] array) { 
    return new Int32ArrayWithOperators(array); 
    } 
    public static implicit operator int[](Int32ArrayWithOperators wrapper) { 
    return wrapper._array; 
    } 

    public static Int32ArrayWithOperators operator +(Int32ArrayWithOperators left, Int32ArrayWithOperators right) { 
    var x = left._array; 
    var y = right._array; 
    return x.Zip(y, (a, b) => a + b).ToArray(); 
    } 
} 

Sulla base di un relativo post che ho scritto.