2010-07-18 32 views
7

Esto es simple de explicar: esto funcionaPila excepción de desbordamiento en C# colocador

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"); 
     } 
    } 
} 

no esto

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"); 
     } 
    } 
} 

me sale una excepción de desbordamiento de pila en seleccionador de en segunda clase y hago no sé por qué. No puedo usar el primer formulario porque no es compatible con el motor de unidad

+0

'No puedo usar la primera forma, ya que no es compatible con la unidad engine' ... La primera forma es una forma rápida de nivel compilador. Debería funcionar bien con el motor de unidad. – SLaks

+1

posible duplicado de [StackOverFlow en la propiedad de la clase] (http://stackoverflow.com/questions/680765/stackoverflow-on-class-property) y muchos otros. –

+0

no, el compilador de unity C# no es compatible con esta sintaxis – Patrik

Respuesta

24

Cuando escribe a = value, está llamando al ajustador de propiedades nuevamente.

Con el fin de utilizar las propiedades de funcionamiento no automático, es necesario crear un campo respaldo privado por separado, así:

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

No estoy seguro de por qué esta respuesta es downvoted tampoco, dado que es más informativo que Cory Larson ... –

+0

@Jon: Me sorprende que obtuve ningún voto cuando publiqué segundos detrás de ti: P. Esta mañana estaba demasiado aturdido para explicar el ** por qué **, así que no hay duda de que tanto SLaks como tus respuestas son mejores. –

+0

@Cory: no tenía nada particularmente en contra de su respuesta, ya que resolvió el problema, pero sin el por qué. Posiblemente alguien simplemente no le gusta a las personas con alta reputación. –

15

No ha declarado una variable respaldo - sólo tiene una propiedad cuyo getters y setters se llaman a sí mismos. No es claro para mí qué la primera forma no es compatible con la unidad - que significa que es posible que el equivalente no será compatible tampoco, pero es básicamente el siguiente:

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

Me normalmente tienen una más nombre convencional, por supuesto - que significa que puede salir sin el "bit valor`:

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

para dar un poco más de detalle en cuanto a por qué su segunda forma actual es lanzar una StackOverflowException, siempre se debe recordar que las propiedades son básicamente métodos disfrazados. Tu código roto se ve así:

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

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

Esperemos que sea obvio por qué esa versión está volando la pila. La versión modificada simplemente establece una variable en lugar de llamar a la propiedad de nuevo, por lo que se parece a esto cuando se expande:

private ConstraintSet aValue; 

public ConstraintSet get_a() 
{ 
    return aValue; 
} 

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

@Downvoter: ¿Te importa dar una razón? –

+0

el compilador simplemente unity C# no admite lo que hace la visual C#. esto es porque tiene que mantener la compatibilidad con mono – Patrik

+0

@Patrik: Mono también admite C# 3 ... C# 3 ha estado fuera por casi 3 años; esto no es exactamente una característica nueva. –

3

Usted necesita una variable respaldo privado en su propiedad pública:

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

No se puede utilizar el mismo nombre de variable dentro del getter y del setter.
Esto hará que se llame a sí mismo y eventualmente stackoverflow. Demasiada recursión.
que necesitará una variable respaldo:

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