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 Réponses :
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: p> 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. P> C'est aussi la raison pour laquelle vous n'avez pas à initier une nouvelle instance lorsque vous l'avez attribuée. P> Voici la réflexion code qui fonctionne: p>
Merci @jeryvanlangen
Pour étendre la réponse de Jeroen:
Opérateur implicite génère une méthode spéciale appelée op_implicite code>. Pour correctement "couler" à l'aide de l'opérateur implicite, vous pouvez appeler cette méthode à l'aide de la réflexion: p>
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.
Et voici une autre approche, à l'aide d'un liant code> personnalisé code> ( 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. P> et lors de l'attribution de la réflexion: p>
Merci @oguz, je cherchais une autre solution, votre solution m'aidera dans un autre scénario.
Qu'attendez-vous? que le
opérateur implicite code> est appelé par magie? C'est Syntaxtic i> sucre. Si vous voulez te définir le texte code> de la propriété code> de
tfdiplay code> qui est une propriété de
TestDaTatype code>. Vous devez utiliser un
getProperty ("texte") code> sur le drapeau
code> 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 code> sur une chaîne sans le liant code> correct code> échouera toujours. Mais, qui essaiera de définir une instance de type de référence en fournissant une chaîne?