2010-06-16 8 views
3

Je tire une valeur "longue" de Session, en utilisant une propriété générique, et elle plante.Pouvez-vous convertir un objet en C#?

J'ai donc:

public static T Get<T>(string key) 
{ 
    if(...) 
     return (T)System.Web.HttpContext.Current.Session[key]; 

    ... 
} 

Lorsque le débogage, la valeur est 4, et il se bloque.

+3

êtes-vous sûr que le long est un long et pas un int? Cela ferait planter la distribution. faire un GetType(). Nom sur la valeur, pour voir le type réel de l'élément. – SWeko

+0

oui c'est un int, la valeur est 4. (voir ci-dessus) – Blankman

+0

Je ne comprends pas pourquoi vous ne pouvez pas lancer 4 à un long? – Blankman

Répondre

8

Si vous insistez pour garder votre méthode générique, vous pouvez utiliser Convert.ChangeType():

public static T Get<T>(string key) 
{ 
    if (...) 
     return 
      (T) Convert.ChangeType(System.Web.HttpContext.Current.Session[key], 
           typeof(T)); 

    ... 
} 

qui vous permettra d'appeler:

long n = Get<long>("sessionkey"); 

Mais attention: Convert.ChangeType() ne fonctionne pas pour toutes les conversions.

+0

Qu'est-ce que ça ne fonctionne pas exactement? Donc, fondamentalement, un getter générique pour les valeurs dans Session ne peut pas être fait "en toute sécurité" à travers tous les types. – Blankman

+0

Si elles peuvent être transtypées d'un type à un autre, Convert.ChangeType() fonctionnera. Mais convertir une chaîne en int ne fonctionnera pas. La documentation peut être trouvée ici: http://msdn.microsoft.com/en-us/library/dtb69x08.aspx –

+0

mais la chaîne à ints fonctionne avec Convert.ToInt32 ("23"); – Blankman

2

Alors, voici où le problème est le suivant:

Vous avez eu un nombre décimal (100 m), qui a obtenu emballé dans un objet (tout en session) et vous essayez de unbox dans une longue, ce qui est là les choses ont frappé le ventilateur.

L'opérateur coulé .net fait deux choses en fait:

object o="string"; 
string s=(string) o 

ici la valeur de l'objet n'a jamais changé, il était la même vieille « string », si était seulement sa référence qui a changé. Cependant, quand je fais

double d= 3.7; 
long l = (long) x; 

Je change réellement la nature même de la chose, la d et l n'ont pas la même représentation, on est un point flottant double largeur avec une valeur de 3,7, et l'autre est un entier de 64 bits avec une valeur de 3.

l'opérateur .net peut faire ces deux choses, cependant, il ne fera pas les en même temps, et c'est où votre problème est ...

decimal d=4m; 
object o = d; 
long l1 = (long)o; //blows up, the runtime error you got 
long l2 = (decimal)o; //compile time error 
long l3 = (long)(decimal)o; //first we unbox, then we convert - works 

BTW, rip sans vergogne du maître (here for more and better explanations)

Questions connexes