0
votes

DataType personnalisé à l'aide de l'opérateur implicite ne fonctionnant pas avec la réflexion

J'ai créé un type de données personnalisé à l'aide de l'opérateur implicite ci-dessous est le code exemple. Lorsque je défini une valeur codée dure sur mon type de données personnalisé, il fonctionne comme prévu, mais définissez la valeur à l'aide d'une erreur de conversion de réflexion. (System.ArgumentException: 'objet de type' system.string 'ne peut pas être converti en type' tf.datataype.tfdiplay '.')

Quelqu'un peut-il m'aider ce que je dois changer pour travailler cela avec des réflexions bien p >

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TF.DataType
{
    public class TFDiplay 
    {
        public TFDiplay() { }
        public TFDiplay(object value, string text) { Value = value; Text = text; }
        public TFDiplay(object value)
        {
            Value = value;
        }

        public static implicit operator TFDiplay(string value)
        {
            var result = new TFDiplay()
            {
                Value = value
            };
            return result;
        }

        public static implicit operator TFDiplay(int value)
        {
            var result = new TFDiplay()
            {
                Value = value
            };
            return result;
        }


        public object Value { get; set; }

        public string Text { get; set; }


    }
}

class Program
{
    static void Main(string[] args)
    {

        TFDiplay tFDiplay;

        tFDiplay = "ss"; //Working as expected
        tFDiplay = 1; //Working as expected

        testDatatype t = new testDatatype();

        Type s = t.GetType();

        PropertyInfo p = s.GetProperty("Flag");

        p.SetValue(t, "ss");  //Throwing error



    }

    public class testDatatype
    {
        public TFDiplay Flag { get; set; }
    }
}


3 commentaires

Qu'attendez-vous? que le opérateur implicite est appelé par magie? C'est Syntaxtic sucre. Si vous voulez te définir le texte de la propriété de tfdiplay qui est une propriété de TestDaTatype . Vous devez utiliser un getProperty ("texte") sur le drapeau de la propriété aussi


@ Jeroenvanlangen, que voulez-vous dire par "getProperty"? Je définit la valeur d'abord en utilisant cette ligne de code de propriétéInfo p = s.geproperty ("drapeau"); Puis définissez la valeur, veuillez clarifier si vous voulez dire autre chose.


Pouvez-vous envisager d'utiliser un classeur? Le code de réflexion ne sera pas le même, vous devez appeler une autre surcharge, mais cela sera toujours une réflexion. D'autres cependant, lorsque vous essayez de définir drapeau sur une chaîne sans le liant correct échouera toujours. Mais, qui essaiera de définir une instance de type de référence en fournissant une chaîne?


3 Réponses :


1
votes

Le problème est que vous ne pouvez pas attribuer une chaîne à un type TFDIPLAY via une réflexion. La réflexion n'utilise pas les convertisseurs implicites. Les convertisseurs implicites sont compilétype. La réflexion est exécutée.

surligneur: xxx

Les opérateurs implicites font le travail pour vous. Chaque fois qu'une chaîne ou un int est affectée à TFDIPLAY, l'opérateur est appelé, un nouveau Tfdisplay est initié. Alors appeler un opérateur sur un objet existant est inutile.

C'est aussi la raison pour laquelle vous n'avez pas à initier une nouvelle instance lorsque vous l'avez attribuée.

Voici la réflexion code qui fonctionne: xxx


1 commentaires

Merci @jeryvanlangen



0
votes

Pour étendre la réponse de Jeroen:

Opérateur implicite génère une méthode spéciale appelée op_implicite . Pour correctement "couler" à l'aide de l'opérateur implicite, vous pouvez appeler cette méthode à l'aide de la réflexion: xxx


3 commentaires

La seule chose est que cela construira une nouvelle instance TFDIPLAY.


@Jeenvanlangen mais quand vous faites .flag = "SS" manuellement, qui est ce que l'OP tente d'atteindre l'utilisation de la réflexion, elle construit également une nouvelle instance.


@Oguzozozgul Je parie qu'il a raté cela.



1
votes

Et voici une autre approche, à l'aide d'un liant personnalisé ( https://docs.microsoft.com/en-us/dotnet/api/system.reflection.binder?view=netframework-4.8 )

Je doute que c'est ce que vous recherchez, mais cela peut aider. Ici, nous implémentons simplement la substitution de Changetype. xxx

et lors de l'attribution de la réflexion: xxx


1 commentaires

Merci @oguz, je cherchais une autre solution, votre solution m'aidera dans un autre scénario.