2010-07-01 6 views
3

Je sais que c'est un peu une bouchée et peut ne pas être totalement compréhensible. Voici donc un exemple de ce que j'essaie de faire. Ce code génère de manière surprenante une erreur RuntimeBinderException: Cannot implicitly convert type 'object' to 'string'. Même si MyString est de type string et ce qui est tenu à o est un string.Affecter une chaîne contenue dans une variable d'objet à une propriété de chaîne d'une dynamique (C#)

est-ce un bug ou une lacune dans le DLR?

est-il un moyen de contourner le problème?

Si je ne sais pas à l'avance le type. Mais je sais que cela respecte le typage du canard. c'est-à-dire que je sais qu'il met en œuvre une interface non écrite. Est-ce que de toute façon je peux assigner une variable à l'autre quand ils sont vraiment le bon type?

Merci beaucoup

Répondre

4

Non, c'est prévu. Le compilateur sait que le type o est object, donc il enregistre une action dynamique de "essayer de trouver une propriété appelée MyString et ensuite essayer de lui affecter une valeur de type object" - il pourrait le faire s'il y avait une conversion implicite de object à string, mais il n'y en a pas. Notez que la seule partie de votre instruction qui est dynamique est la cible ... donc c'est le seul bit qui est traité dynamiquement. ? Au moment de l'exécution, le « compilateur exécution en temps » dira efficacement, « Quel est le type de la valeur réelle de d Ah, c'est TypeWithString ... maintenant, ce qui se passerait si nous avions:

TypeWithString tmpD = (TypeWithString) d; 
tmpD.MyObject = o; 

. .. et ce qui se passerait serait une erreur de compilation

Si vous voulez qu'il se comporte de façon dynamique la valeur aussi bien, il suffit d'utiliser dynamic au lieu de object pour la valeur que vous attribuez.

string s = "We Want Moshiach Now"; 
TypeWithString tws = new TypeWithString(); 
dynamic o = s; 
dynamic d = tws; 
d.MyString = o; 

Cette fois, le "temps d'exécution" compilateur » va se demander le type réel des deux deto valeurs, et imaginez le code comme ceci:

TypeWithString tmpD = (TypeWithString) d; 
string tmpO = (string) o; // Actual type is string at execution time 
tmpD.MyObject = tmpO; 
1

Vous pouvez toujours essayer d.MyString = o as string; qui jetteront (sans lancer) o à une chaîne ou null si la distribution n'existe pas.

+0

B "H Je ne sais pas à l'avance ce que ça va être, sinon je l'aurais simplement stocké dans la bonne variable. – Rabbi

Questions connexes