5
votes

Comment raccourcir le chemin d'accès à une propriété?

Par exemple, si j'ai Object.ObjectTwo.Property et que je ne veux pas encombrer mon code en l'écrivant tout le temps, y a-t-il un moyen de le raccourcir?

Au lieu d'écrire Object.ObjectTwo.Property = something , j'aimerais pouvoir écrire myVariable = something .

Je n'ai rien trouvé lorsque j'ai essayé de faire une recherche.

Edit: Le membre en question est une propriété.

c#

7 commentaires

Peut-être simplement déclarer une variable distincte? ObjectA = Object.ObjectTwo.Variable


Object.ObjectTwo.Variable est-il réellement une variable ? C'est important. C # 7 vous permet de créer de courts alias pour les variables , mais pas pour les propriétés . Les variables locales, les paramètres formels, les éléments de tableau, les champs d'instance, les champs statiques et les déréférences de pointeur non sécurisées sont des variables . Les propriétés ne le sont pas. Lequel est-ce? La Variable est-elle un champ ou une propriété?


Deuxième question: Object et ObjectTwo sont-ils de type référence ou type valeur ?


De plus, pour votre information, à peu près aucune des réponses, y compris celle que vous avez marquée comme correcte, n'est correcte. Il n'y a pas encore suffisamment d'informations dans le problème pour répondre définitivement à la question et le marquer comme répondu était prématuré .


C'est une propriété!


Je travaillais avec Unity. Je travaillais avec une ligne ressemblant à ceci: camera.backgroundColor.r = 1 et je voulais qu'elle soit raccourcie à bgColor = 1. Là où camera est une classe, backgroundColor est une structure et r est un float.


backgroundColor est-il une propriété ou une variable? Il s'agit probablement d'une variable, puisque le code donné ne fonctionnerait pas s'il s'agissait d'une propriété et que la valeur est une structure, car la mutation serait perdue. Plus généralement, la mutation d'un type de valeur comme celui-ci est considérée comme une mauvaise pratique. Comme cette question l'a justement souligné, la sémantique de la mutation des valeurs des champs à valeur struct est très délicate!


7 Réponses :


0
votes

Que diriez-vous de:

var shortCut = Object.ObjectTwo;    
shortCut.Variable  = something;


2 commentaires

De toutes les réponses à ce jour, c'est la seule correcte, et elle n'est correcte que si ObjectTwo est un type de référence.


En effet, il doit s'agir d'un type référence et non d'un type valeur. Votez si vous l'aimez :)



3
votes

Peut-être simplement déclarer une variable séparée?

var ObjectA = Object.ObjectTwo.Variable;

Bien que cela soit plus pratique pour vous, côté ordinateur, c'est une autre variable déclarée.


4 commentaires

Cela changerait-il réellement la valeur d'origine si j'allais ObjectA = quelque chose? Ou s'agit-il simplement de manipuler une copie de l'original?


Non, vous copiez simplement la valeur dans la nouvelle variable. Comme je l'ai mentionné, le compromis pour un code plus facile pour vous ici est que vous aurez une variable supplémentaire dans votre mémoire. Vous seul saurez si cela compte ou non.


Cela s'applique uniquement au cas où, dans Object.ObjectTwo.Variable, Variable est un type de référence. S'il s'agit d'un type valeur, cela ne résout pas le problème.


Hm ... Ce n'est pas exactement ce que j'aurais espéré mais comme personne d'autre ne semble avoir de meilleure réponse, je vais marquer cela comme réponse. Merci à tous pour l'aide!



4
votes

Dans C # , vous pouvez créer des raccourcis pour les types de variables à la portée globale (où vous mettez des instructions telles que using System; ).

Si vous voulez raccourcir Object.ObjectTwo à quelque chose de plus simple, vous pouvez utiliser une instruction using de la manière suivante:

using Object.ObjectTwo = ObjTwo;

Ensuite, vous peut plus tard appeler ObjTwo.Variable = someVar; , et il agira comme si vous aviez utilisé Object.ObjectTwo.Variable = someVar;


0 commentaires

2
votes

Vous pouvez vous donner du sucre syntaxique en implémentant des «raccourcis» qui pourraient vous rapprocher de votre objectif.

var one = new ObjectOne();

one.Var = something;

Cela vous permet d'écrire par exemple:

public class ObjectOne
{
    public ObjectTwo ObjectTwo {get;set;}

    public VariableType Var {get{return ObjectTwo.Variable;}}
}

@Eric Lippert a raison, ce n'est qu'une solution possible, la question a besoin de plus d'informations pour être répondue correctement.


1 commentaires

Eric Lippert fournit une implémentation générique d'une telle classe de raccourci ici .



3
votes

En C # 7, vous pouvez utiliser Locaux de référence . Contrairement à la plupart des autres approches, cette approche peut être utilisée en toute sécurité même en opérant sur des structures.

Cette approche n'est disponible que sur les champs. Les propriétés ne peuvent pas être aliasées en utilisant ref.

Voici un exemple.

struct bar
{
    public int myprop;
}

struct bash 
{
    public bar mybar;
}

void Main()
{
    bash bash1 = new bash();
    bash1.mybar.myprop = 1;
    Console.WriteLine(bash1.mybar.myprop); //Outputs 1 (Direct access)

    bar bar2 = bash1.mybar;
    bar2.myprop = 2;
    Console.WriteLine(bash1.mybar.myprop); //Outputs 1 (Bug: access via a copy)

    ref bar bar3 = ref bash1.mybar;
    bar3.myprop = 3;
    Console.WriteLine(bash1.mybar.myprop); //Outputs 3 (Ref Local)

    bar3 = new bar();
    bar3.myprop = 4;
    Console.WriteLine(bash1.mybar.myprop); //Outputs 4 (Ref local with assignment)
}


1 commentaires

@Mawkey: Je pense que C # 7 nécessite Unity 2018.3 ou supérieur.



0
votes

L'exemple camera.backgroundColor.r = 1 de comment ne fonctionnera tout simplement pas. Vous obtiendrez l'erreur suivante

Impossible de modifier la valeur de retour de 'Camera.backgroundColor' car ce n'est pas une variable

et la raison a été discutée ici a>. Le fait est que dans Unity la Camera elle-même est la classe mais la Color (le type de la backgoundColor ) est mutable struct , faites attention bien qu'ils soient mauvais.


Lorsque vous attribuez une nouvelle valeur à une variable d'un type valeur, cette valeur est copié. Lorsque vous affectez une nouvelle valeur à une variable d'une référence type, la référence est copiée, pas l'objet lui-même

var shortCutRef = cammera.backgroundColorRef;
camera.backgroundColorRef = new BackgroundColorRef(); //link to shortcut broken
shortCutRef.r = 10;

//cammera.backgroundColorRef.r == 0, shortCutValue == 10

Les types de valeur sont copiés par valeur afin que shortCutValue n'ait aucune connexion avec la caméra .backgroundColor.r sauf qu'ils ont la même valeur dans une période de leur existence. D'un autre côté, shortCutRef est un raccourci réel et il fonctionnera jusqu'à ce que vous changiez la référence à backgroundColorRef , ce qui pourrait être possible si Camera est mutable.

public class Camera
{
    public BackgroundColorValue backgroundColorValue { get; set; } 
        = new BackgroundColorValue();
    public BackgroundColorRef backgroundColorRef { get; set; } 
        = new BackgroundColorRef();
}

public struct BackgroundColorValue
{
    public int r { get; set; }
    public int g { get; set; }
    public int b { get; set; }
}

public class BackgroundColorRef
{
    public int r { get; set; }
    public int g { get; set; }
    public int b { get; set; }
}

var shortCutValue = cammera.backgroundColorValue;
var shortCutRef = cammera.backgroundColorRef;

shortCutValue.r = 5;
shortCutRef.r = 10;

//cammera.backgroundColorValue.r == 0, shortCutValue == 5
//cammera.backgroundColorRef.r == 10, shortCutValue == 10

Je ne suis pas sûr que cela soit applicable en général, il se peut que Eric le sache, mais si vous avez ABCD ... Nr vous pouvez faire un raccourci si N est en fait du type reference et pour être sûr que le lien avec le raccourci sera incassable tous les types de N à A doivent être immuable. Sinon, vous pourriez casser un lien quelque part.


0 commentaires

0
votes

Utilisez une fonction locale (ou sur les versions C # <7.0 un délégué).

 XXX 


0 commentaires