Specified cast is not valid.

Signaler
Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
-
Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
-
Tout d'abord, trois petites question :



Est-il possible d'hériter d'une classe dont tous les constructeurs sont
"private" ? En fait elle crée ses instances à partir d'une méthode
statique sur le schema de System.Reflection. Assembly
System.Reflection.Assembly.LoadFrom (string).



Quand une exception survient dans un constructeur, qu'advient-il de
l'instance que ce constructeur était censé initialiser ? Je m'explique
: si j'étais sûr qu'en cas d'erreur ce sera bien un null qui sera
retourné par la new à la référence et pas l'adresse d'une instance à
moitié initialisée, inutilisable et provoquant des erreurs en série, je
pourrais me passer d'utiliser une ****** de methode statique comme
substitut au constructeur.



Est-il possible de forcer un constructeur à renvoyer null à la
référence dans un cas particulier comme on ferait un return null dans
une méthode classique ?



Ensuite, plus compliqué :-p !



C'est un système de classes destiné à l'internationalisation (programme
polyglotte). La classe de base est Excubitor.Binders.LateBinder (je
n'inclus pas le code des méthodes pour ne pas encombrer mais si il vous
intéresse n'hésitez pas à le demander, j'enverrai les fichiers du
projet et de toute façon tout sera posté sur ce site quand je jugerai le travail digne d'intérêt) :



La classe de base :



namespace Excubitor.Binders

{

public class LateBinder

{

private System.Reflection.Assembly Assembly ;

private System.Type Type ;

private object Instance ;



protected internal LateBinder () {}



public static LateBinder Load (string Path, string Type) {[...]}



protected object InvokeMethod (string Name, object[] Arguments) {[...]}



public static event Excubitor.Delegates.ExceptionHandler AssemblyLoadingFailed ;

public static event Excubitor.Delegates.ExceptionHandler TypeLoadingFailed ;

public static event Excubitor.Delegates.ExceptionHandler InstanceCreationFailed ;



public event Excubitor.Delegates.MethodInvokeExceptionHandler MethodInvocationFailed ;

}

[...]

}



Les délégates en question (même si je doute que le problème vienne de la) :



namespace Excubitor.Delegates

{

public delegate void ExceptionHandler (object Sender, System.Exception Exception) ;

public delegate void MethodInvokeExceptionHandler
(object Sender, System.Exception Exception, string Name, object[]
Arguments) ;

[...]

}



Voici maintenant un exemple d'héritage :



namespace Excubitor.Sodalitas.Languages

{

public interface Language

{

string Hello () ;

}

}



namespace Excubitor.Sodalitas.Sodalitas

{

public class LateLanguageBinder : Excubitor.Binders.LateBinder, Excubitor.Sodalitas.Languages.Language

{

public string Hello ()

{

return (string) (this.InvokeMethod ("Hello", null)) ;

}

}



}



Et la librairie qui va avec :



namespace Excubitor.Sodalitas.Languages

{

class French : Language

{

public string Hello ()

{

return "Bonjour" ;

}

}

}



L'intérêt est évidemment de pouvoir gérer des languages complexes en
composant les phrases à l'aide d'arguments passés à la méthode,
d'appeler cette méthode comme s'il s'agissait d'une méthode locale
("Language.Hello ()") et ce sans même savoir quelle DLL a été
late-bound.



Mais c'est là que ça cloche :



LateLanguageBinder Language = LateLanguageBinder.Load
(@"E:\Programmation\Excubitor\Sodalitas\Languages\French\bin\Debug\French.dll",
"Excubitor.Sodalitas.Languages.French") ;



E:\Programmation\Excubitor\Sodalitas\Sodalitas\MainClass.cs(7): Cannot
implicitly convert type 'Excubitor.Binders.LateBinder' to
'Excubitor.Sodalitas.Sodalitas.LateLanguageBinder'



Ceci ne râle pas à la compilation mais plante à l'exécution :



LateLanguageBinder Language = (LateLanguageBinder)
LateLanguageBinder.Load
(@"E:\Programmation\Excubitor\Sodalitas\Languages\French\bin\Debug\French.dll",
"Excubitor.Sodalitas.Languages.French") ;



An unhandled exception of type 'System.InvalidCastException' occurred in Sodalitas.exe



Additional information: Specified cast is not valid.



Je comprends le problème : j'essaye de faire passer un cube dans un trou triangulaire et .NET n'aime pas ça !



Mais la solution ... je sèche. Et vous ?

4 réponses

Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
39
Salut, utilises un constructeur protected pour dériver ta classe. En cas d'exception dans un constucteur l'object n'est pas créé, ( à moins de catcher l'exception à l'interieur du ctor. ) Pour les ctor statics c'est différent une TypeInitialisationException est lancée.
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Salut,

Normalement oui ce sera null.
Sinon :
MaClasse monInstance;
try
{
monInstance = new MaClasse();
}
catch
{
monInstance = null;
}

Pour ton 2eme problème, tu peux peut être essayer de mettre en place une conversion explicite afin qu'un "Langage" puisse être converti en "LateLanguageBinder" sans relation d'héritage entre eux.
http://msdn.microsoft.com/library/fre/default.asp?url=/library/fre/csref/html/vclrfExplicit.asp

Mais là je ne vois pas pourquoi tu ne te sert pas de l'interface "Langage" définie justement, ils l'implémentent tous les 2 ?

/*
coq
MVP Visual C#
*/
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
39
On peu caster une classe derivée vers sa classe de base, mais l'inverse n'est pas possible.
Messages postés
72
Date d'inscription
vendredi 16 mai 2003
Statut
Membre
Dernière intervention
12 août 2009
2
Merci pour votre aide.



Je vais faire une série de tests pour vérifier la fiabilité des valeurs de retour des constructeurs.