variable valores tipos retorno retornan referencia que por pasar pasaje parametros objetos metodos metodo funciones con como c# variables struct immutability

valores - pasar objetos como parametros en c#



No se puede modificar el error de valor de retorno c# (5)

El problema es que apunta a un valor ubicado en la pila y el valor no se volverá a relacionar con la propiedad original, por lo que C # no le permite devolver una referencia a un tipo de valor. Creo que puedes resolver esto quitando la propiedad Origin y en su lugar usar un archivo público, sí, sé que no es una buena solución. La otra solución es no usar el Punto, y en su lugar crear su propio Tipo de Punto como un objeto.

Estoy usando propiedades implementadas automáticamente. Supongo que la forma más rápida de corregir lo siguiente es declarar mi propia variable de respaldo.

public Point Origin { get; set; } Origin.X = 10; // fails with CS1612

Mensaje de error: No se puede modificar el valor de retorno de ''expresión'' porque no es una variable

Se intentó modificar un tipo de valor que fue el resultado de una expresión intermedia. Como el valor no se conserva, el valor no cambiará.

Para resolver este error, almacene el resultado de la expresión en un valor intermedio, o use un tipo de referencia para la expresión intermedia.


Esto se debe a que Point es un tipo de valor ( struct ).

Debido a esto, cuando accede a la propiedad Origin está accediendo a una copia del valor de la clase, no al valor en sí mismo como lo haría con un tipo de referencia ( class ), por lo que si establece la propiedad X en él, entonces usted está configurando la propiedad en la copia y luego descartándola, sin modificar el valor original. Probablemente esto no sea lo que pretendías, y es por eso que el compilador te advierte al respecto.

Si desea cambiar solo el valor X , debe hacer algo como esto:

Origin = new Point(10, Origin.Y);


Por ahora ya sabes cuál es la fuente del error. En caso de que no exista un constructor con una sobrecarga para tomar su propiedad (en este caso X ), puede usar el inicializador de objetos (que hará toda la magia detrás de las escenas). No es que no necesite que sus estructuras sean inmutables , sino que simplemente brinde información adicional:

struct Point { public int X { get; set; } public int Y { get; set; } } class MyClass { public Point Origin { get; set; } } MyClass c = new MyClass(); c.Origin.X = 23; //fails. //but you could do: c.Origin = new Point { X = 23, Y = c.Origin.Y }; //though you are invoking default constructor //instead of c.Origin = new Point(23, c.Origin.Y); //in case there is no constructor like this.

Esto es posible porque detrás de escena sucede esto:

Point tmp = new Point(); tmp.X = 23; tmp.Y = Origin.Y; c.Origin = tmp;

Esto parece una cosa muy extraña, no recomendada en absoluto. Solo haciendo una lista de una manera alternativa. La mejor forma de hacerlo es hacer que la estructura sea inmutable y proporcionar un constructor adecuado.


Supongo que la trampa aquí es que estás tratando de asignar subvalores de objeto en la declaración en lugar de asignar el objeto en sí. Debe asignar todo el objeto Point en este caso ya que el tipo de propiedad es Point.

Point newOrigin = new Point(10, 10); Origin = newOrigin;

Espero que tenga sentido allí


Usar una variable de respaldo no ayudará. El tipo de Point es un tipo de valor.

Debe asignar todo el valor de Punto a la propiedad Origen: -

Origin = new Point(10, Origin.Y);

El problema es que cuando accede a la propiedad Origin, lo que devuelve el get es una copia de la estructura de puntos en el campo de creación automática de propiedades de origen. De ahí su modificación del campo X esta copia no afectaría el campo subyacente. El compilador detecta esto y le da un error ya que esta operación es completamente inútil.

Incluso si usó su propia variable de respaldo, su resultado se vería así: -

get { return myOrigin; }

Todavía estaría devolviendo una copia de la estructura de puntos y obtendría el mismo error.

Hmm ... habiendo leído tu pregunta más detenidamente, quizás realmente quieras modificar la variable de respaldo directamente desde dentro de tu clase:

myOrigin.X = 10;

Sí, eso sería lo que necesitarías.