Impossible de modifier l’erreur de valeur de retour c #

J’utilise des propriétés implémentées automatiquement. Je suppose que le moyen le plus rapide de corriger est de déclarer ma propre variable de sauvegarde?

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

Message d’erreur: Impossible de modifier la valeur de retour de ‘expression’ car il ne s’agit pas d’une variable

Une tentative de modification d’un type de valeur résultant d’une expression intermédiaire a été effectuée. Étant donné que la valeur n’est pas persistante, la valeur sera inchangée.

Pour résoudre cette erreur, stockez le résultat de l’expression dans une valeur intermédiaire ou utilisez un type de référence pour l’expression intermédiaire.

C’est parce que Point est un type de valeur ( struct ).

De ce fait, lorsque vous accédez à la propriété Origin , vous accédez à une copie de la valeur détenue par la classe, et non à la valeur elle-même, comme vous le feriez avec un type de référence ( class ). Vous définissez la propriété sur la copie, puis vous la supprimez, en laissant la valeur d’origine inchangée. Ce n’est probablement pas ce que vous vouliez, c’est pourquoi le compilateur vous en avertit.

Si vous souhaitez modifier uniquement la valeur X , vous devez faire quelque chose comme ceci:

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

Utiliser une variable d’accompagnement n’aidera pas. Le type de Point est un type de valeur.

Vous devez affecter la valeur Point entière à la propriété Origin:

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

Le problème est que lorsque vous accédez à la propriété Origin, ce qui est renvoyé par get est une copie de la structure Point dans le champ créé automatiquement par les propriétés Origin. D’où votre modification du champ X cette copie n’affecterait pas le champ sous-jacent. Le compilateur le détecte et vous donne une erreur car cette opération est totalement inutile.

Même si vous utilisiez votre propre variable de sauvegarde, votre get ressemblerait à ceci:

 get { return myOrigin; } 

Vous retournerez toujours une copie de la structure Point et vous obtiendrez la même erreur.

Hmm … après avoir lu votre question avec plus de soin, vous voulez peut-être modifier directement la variable de sauvegarde depuis votre classe: –

 myOrigin.X = 10; 

Oui, ce serait ce dont vous auriez besoin.

Vous savez déjà quelle est la source de l’erreur. Si un constructeur n’existe pas avec une surcharge pour prendre votre propriété (dans ce cas X ), vous pouvez utiliser l’initialiseur d’object (qui fera toute la magie dans les coulisses). Non pas que vous n’ayez pas à rendre vos structures immuables , mais simplement à donner des informations supplémentaires:

 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. 

C’est possible parce que dans les coulisses cela se produit:

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

Cela ressemble à une chose très étrange à faire, pas du tout recommandé. Il suffit de lister une autre manière. La meilleure façon de faire est de rendre struct immutable et de fournir un constructeur approprié.

Le problème est que vous pointez sur une valeur située sur la stack et que la valeur ne sera pas redéfinie sur la propriété orignal afin que C # ne vous permette pas de renvoyer une référence à un type de valeur. Je pense que vous pouvez résoudre ce problème en supprimant la propriété Origin et en utilisant un fichier public, oui, je sais que ce n’est pas une bonne solution. L’autre solution consiste à ne pas utiliser le point, mais à créer votre propre type de point en tant qu’object.

Je suppose que le problème est que vous essayez d’atsortingbuer des sous-valeurs d’object dans l’instruction plutôt que d’affecter l’object lui-même. Dans ce cas, vous devez affecter l’intégralité de l’object Point car le type de propriété est Point.

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

J’espère que j’ai bien compris