J'ai une classe en tant que tel où, maintenant , J'ai cette méthode utilitaire p> quelle fonction vérifie évidemment le type de L'erreur est p> ne peut pas lancer l'expression de t à Twotype p>
blockQuote> p> Twotype code> est dérivé de
iNetype code>. p>
vd code>, et la création d'un
approprié> myClass < / code> type. Le seul problème est que le code ci-dessus ne compile pas, et je ne sais pas pourquoi P>
9 Réponses :
Modifiez votre méthode d'usine: alors vous n'avez pas besoin du commutateur du tout. p> p>
Pourquoi cela est bullevé? C'est la seulement i> réponse (sur 7 jusqu'à présent) qui peut compiler.
Son ne va pas fonctionner dans .NET 3.5 et ci-dessous - la sous-classe n'est pas de type Malheureusement, je ne connais pas une façon raisonnable d'écrire votre méthode d'usine. P> myClass
myClass
myClass
myClass
Cast à l'objet en premier, tromper le compilateur en permettant la conversion.
Cela ne fonctionnera pas dans le C # 4 non plus. Nous ajoutons des conversions variantes sur des interfaces génériques et des délégués, mais pas sur les classes.
Vous n'avez pas la contrainte pour T sur votre méthity méthode.
public static MyClass<T> Factory<T>(T vd) where T: OneType { // ... }
Après avoir lu la réponse au-dessus de la mine (de Grzenio), je me souviens de courir dans le même problème. Je ne pense pas que vous puissiez faire ce que vous essayez de faire. Au moins, pas avant .net 4.0 peut-être?
Nope, c n ° 4 ne rend pas mieux cela. Seules les interfaces et les délégués auront des conversions de covariant, pas des cours.
Pouvez-vous retourner le design autour de la conception? Au lieu de créer une méthode d'usine inflexible qui doit connaître toutes les sous-classes de onetype code>, ajoutez une méthode abstraite sur
oneType code> qui ressemble à ceci;
public class TwoType: MyClass<TwoType>
{
public override MyClass<OneType> GetMyClass()
{
return new SubClass(this);
}
}
Le problème est que j'ai besoin de créer le myClass code> selon
* Type code> transmis.
(publié édité pour donner l'exemple.) Tenez-vous maintenant. Vous n'avez pas de type myclass. Vous avez un nombre sans fin type - MyClass
Cela devrait fonctionner:
return (MyClass<T>)(object)new SubClass((TwoType)(object)vd);
Ça ne marche pas. Le message est ne peut pas convertir le type 'ClassLibrary1.Subclass' en "ClassLibrary1.myclass
sous-classe code> n'est pas
myClass
Êtes-vous sûr de ne pas manquer que (objet) code> coule entre
nouvelle sous-classe code> et
(myClass
Comme grzenio note correctement, une expression de type T n'est pas convertible au tatype. Le compilateur ne sait pas que l'expression est garantie de type Twotype - qui est garantie par votre relevé "Si", mais le compilateur ne considère pas l'implication de la déclaration IF lors de l'analyse des types. Au contraire, le compilateur suppose que T peut être n'importe quel type satisfaisant la contrainte, y compris ThreeType, un type dérivé d'OneType mais pas de dwotype. Évidemment, il n'y a pas de conversion du ThreeType sur Twotype, et il n'y a donc pas de conversion de T sur TwoType non plus.
Vous pouvez tromper le compilateur à lui permettre en disant «Eh bien, traitez le T comme objet, puis jetez l'objet à Twotype ". Chaque étape du chemin est legal - T est convertible en objet, et il pourrait y avoir une conversion d'objet sur Twotype, de sorte que le compilateur le permet. P>
Vous aurez ensuite le même problème de conversion de la sous-classe à Cependant, ce code est toujours faux: p> pourquoi est-ce faux? Eh bien, considérons tout ce qui pourrait aller mal ici. Par exemple: vous dites p> Que se passe-t-il? Nous n'appelons pas le constructeur de sous-classe car l'argument n'est pas exactement de type Twotype, il est d'un type dérivé du double-type. Au lieu d'un commutateur, vous voulez probablement P> myClass
public static MyClass<T> Factory<T>(T vd)
where T:OneType
{
if (vd is TwoType && typeof(T) == typeof(TwoType))
return (MyClass<T>)(object)(new SubClass((TwoType)(object)vd));
// snip for other type check
}
Ceci fonctionne pour moi: dans mon formulaire, j'ai eu ceci: p> édition: évidemment ce n'est pas idéal comme Eric souligne ci-dessus. Alors que ce code compile techniquement et fonctionne dans une certaine mesure, vous pouvez trouver une meilleure solution globale. P> p>
incroyable, je l'ai utilisé en écrivant le code comme tel: ou p> mais, p> < Pré> xxx pré> ne fonctionne pas. p> Il semble y avoir une différence dans comme code> et
() code> casting. p> p>
Je sais que c'est une vieille question, mais je pense que cela mérite également une réponse à pourquoi em> cela est impossible (sans utiliser divers travaux de contournement laids). Lorsque vous utilisez des génériques, vous êtes , dans un sens, travailler avec le code de modèle. Le compilateur utilise un ensemble plus strict de règles pour votre code, car il doit également être compiler au moment de l'exécution, où la version finale est compilée. P> Ainsi, lorsque vous créez des cours ou des méthodes avec des génériques, ils doivent être compiler pour J'ai donc simplifié votre code encore pour vous montrer ce qui se passe: Je déclare d'abord 3 classes. Une classe mère et deux enfants: p> i puis déclarent une méthode générique où j'essaie de tester le type, puis de vous lancer sur le type enfant: P> public void InvalidMethod(Sister input)
{
Child castedReference = null;
// Following 'if' is never true
if (input is Child)
{
// Following statement is invalid C#
castedReference = (Child)input;
}
// Do stuff...
}
Quelle erreur est le revenu du compilateur?