2011-02-27 9 views
5

Ho iniziato a programmare con C# alcuni giorni fa.L'overloading dell'operatore provoca un overflow dello stack

Ora si è verificato un errore di confusione quando si gioca con il sovraccarico dell'operatore.

Il seguente codice produce un StackOverflowException durante l'esecuzione:

using System; 

namespace OperatorOverloading 
{ 
    public class Operators 
    { 
     // Properties 
     public string text 
     { 
      get 
      { 
       return text; 
      } 

      set 
      { 
       if(value != null) 
        text = value; 
       else 
        text = ""; 
      } 
     } 

     // Constructors 
     public Operators() : this("") 
     { 
     } 

     public Operators(string text) 
     { 
      // Use "set" property. 
      this.text = text; 
     } 

     // Methods 
     public override string ToString() 
     { 
      return text; 
     } 

     // Operator Overloading 
     public static string operator +(Operators lhs, Operators rhs) 
     { 
      // Uses properties of the passed arguments. 
      return lhs.text + rhs.text; 
     } 

     public static void Main(string[] args) 
     { 
      Operators o1 = new Operators(); 
      Operators o2 = new Operators("a"); 
      Operators o3 = new Operators("b"); 

      Console.WriteLine("o1: " + o1); 
      Console.WriteLine("o2: " + o2); 
      Console.WriteLine("o3: " + o3); 

      Console.WriteLine(); 

      Console.WriteLine("o1 + o2: " + (o1 + o2)); 
      Console.WriteLine("o2 + o3: " + (o2 + o3)); 
     } 
    } 
} 

ho provato a scrivere un proprio esempio dopo aver letto il capitolo sul operater sovraccaricare dal libro "Microsoft Visual C# 2008" da Dirk Louis e Shinja Strasser.

Forse qualcuno ha la più pallida idea di cosa non va.

Grazie.

+0

dove si verifica l'errore? –

+0

il tuo Main è all'interno della classe Operators, è qualcosa che volevi fare di proposito? –

+0

Solo curioso ... perché la risposta accettata cambia dal mio al curioso geek? Le regole generali indicano la prima risposta che ha fornito una soluzione operativa come accettata. –

risposta

2

L'ottenere il codice di blocco nella classe ha il problema e che è ciò che sta causando l'eccezione di StackOverFlow.

public string text 
    { 
     get 
     { 
      return text; 
     } 
    } 

Qui quando si dice return text; andrà e richiamare il blocco Get della proprietà text stessa che sta causando lo stack overflow. racchiudere il testo della proprietà attorno a un campo stringa _txt privato e dovrebbe funzionare correttamente.

Si può fare qualcosa di simile ..

private string _txt; 
public string text 
{ 
    get 
    { 
     return _txt; 
    } 

    set 
    { 
     _txt = string.IsNullOrEmpty(value) ? string.Empty : value; 
    } 
} 
10

Bene, per esempio, l'overloading dell'operatore non infrange il codice. Otterrai uno StackOverflowException perché il getter della tua proprietà text sta tentando di restituire se stesso.

È necessario utilizzare un campo di supporto per la vostra proprietà:

private string _text; 

public string Text 
{ 
    get { return _text; } 
    set 
    { 
     if (value != null) 
      _text = value; 
     else 
      _text = string.Empty; 
    } 
} 

Cosa .NET fa sotto le coperte è convertire la vostra proprietà in una funzione di accesso e mutatore - due metodi separati. Nel tuo esempio originale, il codice avrebbe fatto la seguente:

private string text; 

public string get_text() 
{ 
    return get_text(); // <-- StackOverflowException 
} 

public void set_text(string value) 
{ 
    this.text = value; 
} 

considerando che la versione corretta utilizza il campo supporto correttamente:

private string text; 

public string get_text() 
{ 
    return this.text; // Happy :) 
} 

public void set_text(string value) 
{ 
    this.text = value; 
} 
+1

Vedo un sacco di sovraccarico dell'operatore. Tuttavia, hai ragione nella tua risposta. –

+0

@Mike - Sì, non sono riuscito a scorrere abbastanza lontano. Whoopsy! –

+0

Oh, grazie. Che peccato. :(Troppe righe di codice oggi –

1

Il problema è che il testo proprty si ritorna si dovrebbe avere un protetti o privati ​​variab le per memorizzare il resut:

// Properties 
    private string _text 
    public string text 
    { 
     get 
     { 
      return _text; 
     } 

     set 
     { 
      if(value != null) 
       _text = value; 
      else 
       _text = ""; 
     } 
    } 
+0

Grazie amico, problema risolto :) –