8
votes

Pourquoi la réflexion ne définit-elle pas une propriété dans une structure?

   class PriceClass {

        private int value;
        public int Value
        {
            get { return this.value; }
            set { this.value = value; }
        }           
    }


    struct PriceStruct
    {

        private int value;
        public int Value
        {
            get { return this.value; }
            set { this.value = value; }
        }
    }
    static void Main(string[] args)
    {
        PriceClass _priceClass = new PriceClass();
        Type type = typeof(PriceClass);
        PropertyInfo info = type.GetProperty("Value");
        info.SetValue(_priceClass, 32, null);
        Console.WriteLine(_priceClass.Value);

        PriceStruct _priceStruct = new PriceStruct();
        type = typeof(PriceStruct);
        info = type.GetProperty("Value");
        info.SetValue(_priceStruct, 32, null);
        Console.WriteLine(_priceStruct.Value);

        Debugger.Break();
    }
The first value printed is 32 while the second is 0. No exception thrown

1 commentaires

Voir la réponse acceptée à cette question: Stackoverflow.com/Questtions/6280506/...


3 Réponses :


1
votes

Vous pouvez toujours les changer en utilisant la réflexion, mais c'est un peu long enroulement.

Voir cet exemple: http: //social.msdn.microsoft.com/forums/fr/netfxbcl/thread/2dd4315c-0d0d-405c-8d52-B4B176997472


1 commentaires

+1 Votre exemple montre que je pense que le meilleur qui peut être fait. Il n'est pas possible dans le code "Safe" de modifier un champ dans un type de valeur authentique à l'aide de la réflexion, mais pour chaque type de valeur, il existe un type de classe en boîte correspondant. La coulée à l'élevage ironiquement nommé convertira une valeur de valeur en une instance de son type de classe boxe correspondant, qui peut ensuite être muté à l'aide de la réflexion; Après la mutation, le contenu de l'instance boxée peut être copié à un véritable objet de type valeur.



5
votes

Les structures sont des valeurs de valeur, qui sont transmises par une valeur, cela signifie que vous ne transmettez que des copies de la structure entière, et non une référence à l'objet d'origine.

Alors, quand vous le transmettez dans info.sevalue (_pricstract, 32, null) , une copie est transmise à la méthode et muté, donc l'objet d'origine ne " t être changé du tout. Une autre raison pour laquelle les structures mutables sont diaboliques.


0 commentaires

12
votes

C'est parce que la boxe de votre structure en fait une copie, vous devez donc la repasser plus tôt afin d'appeler le getter des mêmes données que vous avez modifiées. Le code suivant fonctionne:

    object _priceStruct = new PriceStruct(); //Box first
    type = typeof(PriceStruct);
    info = type.GetProperty("Value");
    info.SetValue(_priceStruct, 32, null);
    Console.WriteLine(((PriceStruct)_priceStruct).Value); //now unbox and get value

    Debugger.Break();


1 commentaires

Merci. C'est la première fois que j'ai vue de la boxe forcée (transformer une structure dans un objet) et un incorporant (retourner l'objet dans une structure) pour voir ce qui se passe et comprend le processus. C'est simple, vraiment. Mais partout ailleurs j'ai regardé, les étapes de boxe ont toutes été effectuées par des processus cachés (automatiquement par le compilateur) et il n'a aucun sens comment on pourrait travailler avec elle.