2010-07-18 22 views
7

Questo è semplice da spiegare: questo funzionastack eccezione di overflow in C# setter

using System; 
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>; 

namespace ConsoleApplication2 
{ 
    class test 
    { 
     public ConstraintSet a { get; set; } 
     public test() 
     { 
      a = new ConstraintSet(); 
     } 
     static void Main(string[] args) 
     { 
      test abc = new test(); 
      Console.WriteLine("done"); 
     } 
    } 
} 

non questo non

using System; 
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>; 

namespace ConsoleApplication2 
{ 
    class test 
    { 
     public ConstraintSet a { get { return a; } set { a = value; } } 
     public test() 
     { 
      a = new ConstraintSet(); 
     } 
     static void Main(string[] args) 
     { 
      test abc = new test(); 
      Console.WriteLine("done"); 
     } 
    } 
} 

ottengo un'eccezione di overflow dello stack su di un setter in seconda classe e lo faccio non so perché Non riesco ad utilizzare il primo modulo perché non è supportato dal motore dell'unità

+0

'Non posso usare la prima forma, perché non è supportato da unità engine' ... La prima forma è una scorciatoia a livello compilatore. Dovrebbe funzionare bene con il motore dell'unità. – SLaks

+1

possibile duplicato di [StackOverFlow sulla proprietà della classe] (http://stackoverflow.com/questions/680765/stackoverflow-on-class-property) e molti altri. –

+0

no, il compilatore unity C# non supporta questa sintassi – Patrik

risposta

24

Quando si scrive a = value, si sta chiamando di nuovo il setter di proprietà.

Per poter utilizzare le proprietà non automatico, è necessario creare un campo separato supporto privato, in questo modo:

ConstraintSet a; 
public ConstraintSet A { get { return a; } set { a = value; } } 
+1

Non so perché anche questa risposta sia downvoted, dato che è più informativo che Cory Larson abbia ... –

+0

@Jon: Sono sorpreso di avere qualche voto quando ho postato solo secondi dietro di te: P. Sono stato troppo noioso stamattina per spiegare il ** perché **, quindi senza dubbio entrambi gli SLaks e le tue risposte sono migliori. –

+0

@Cory: non avevo nulla di particolarmente contro la tua risposta, in quanto ha risolto il problema - ma senza il perché. Forse a qualcuno non piacciono le persone con un alto rappresentante. –

15

Non hai dichiarato una variabile supporto - hai appena avuto una proprietà il cui Getter e setter si chiamano. Non è chiaro per me perché la prima forma non è supportata da Unity - che significa che è possibile che l'equivalente non sarà supportato sia, ma è fondamentalmente questo:

private ConstraintSet aValue; 
public ConstraintSet a { get { return aValue; } set { aValue = value; } } 

avrei normalmente hanno un altro nome convenzionale, naturalmente - che significa che si può uscire senza il "bit value`:

private ConstraintSet constraints; 
public ConstraintSet Constraints 
{ 
    get { return constraints; } 
    set { constraints = value; } 
} 

per dare un po 'più in dettaglio sul motivo per cui la vostra seconda forma attuale sta gettando un StackOverflowException, si dovrebbe sempre ricordare che le proprietà sono fondamentalmente metodi mascherati. Il tuo codice danneggiato è il seguente:

public ConstraintSet get_a() 
{ 
    return get_a(); 
} 

public void set_a(ConstraintSet value) 
{ 
    set_a(value); 
} 

Speriamo che sia ovvio perché quella versione sta facendo esplodere lo stack. La versione modificata solo imposta una variabile invece di chiamare di nuovo la proprietà, in modo che appaia come questo, quando ampliato:

private ConstraintSet aValue; 

public ConstraintSet get_a() 
{ 
    return aValue; 
} 

public void set_a(ConstraintSet value) 
{ 
    aValue = value; 
} 
+0

@Downvoter: ti interessa dare una ragione? –

+0

semplicemente il compilatore C# di unità non supporta ciò che fa C# visivo. questo perché deve mantenere la compatibilità con mono – Patrik

+0

@Patrik: Mono supporta anche C# 3 ... C# 3 è uscito da quasi 3 anni; questa non è esattamente una nuova funzionalità. –

3

Hai bisogno di un variabile di supporto privato nella vostra proprietà pubblica:

private ConstraintSet _a; 
public ConstraintSet a { get { return _a; } set { _a = value; } } 
3

Non è possibile utilizzare lo stesso nome di variabile all'interno del getter e setter.
Ciò causerà la chiamata a se stessa e infine lo stackoverflow. Troppa ricorsione.
Avrete bisogno di una variabile di supporto:

private ConstraintSet _a; 
public ConstraintSet a { get { return _a; } set { _a = value; } } 
Problemi correlati