2011-08-18 2 views
3

J'ai une propriété de type object, qui contient une valeur Enum, et lorsque je la cast en utilisant (int)value, elle renvoie string du nom Enum. Pourquoi?Pourquoi la conversion d'une énumération stockée dans un objet en int renvoie-t-elle une chaîne?

Le code où j'ai remarqué ceci est dans this answer. L'utilisation de Convert.ToInt32() convertit correctement le Enum en int, mais j'étais curieux de savoir pourquoi j'obtiendrais une chaîne en utilisant (int). Cela ne me jette même pas une erreur.

Modifier

Voici un échantillon rapide. J'ai commenté où j'ai mis le point d'arrêt, et utilisais la fenêtre immédiate pour déterminer ce que la sortie était.

MainWindow.xaml.cs

public partial class MainWindow : Window 
{ 
    public Int32 SomeNumber { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 

     SomeNumber = 1; 
     RootWindow.DataContext = this; 

    } 
} 

public enum MyEnum 
{ 
    Value1 = 1, 
    Value2 = 2, 
    Value3 = 3 
} 


/// <summary> 
/// Returns true if the int value equals the Enum parameter, otherwise returns false 
/// </summary> 
public class IsIntEqualEnumParameterConverter : IValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (parameter == null || value == null) return false; 

     if (parameter.GetType().IsEnum && value is int) 
     { 
      // Breakpoint here 
      return (int)parameter == (int)value; 
     } 
     return false; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

MainWindow.xaml

<Window x:Class="WpfApplication5.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication5" 
     Title="MainWindow" Height="350" Width="525" 
     x:Name="RootWindow"> 

    <Window.Resources> 
     <local:IsIntEqualEnumParameterConverter x:Key="IsIntEqualEnumParameterConverter" /> 
    </Window.Resources> 

    <StackPanel> 
     <TextBlock Text="{Binding SomeNumber, Converter={StaticResource IsIntEqualEnumParameterConverter}, ConverterParameter={x:Static local:MyEnum.Value1}}" /> 
    </StackPanel> 
</Window> 

Edit # 2

Juste l'espoir d'éclaircir une certaine confusion ...

I a dit qu'il renvoyait une chaîne parce que le fonctionnement ?((int)parameter) dans la fenêtre Exécution renvoyait le nom d'enum, tandis que l'exécution ?System.Convert.ToInt32(parameter) affichait correctement l'int.

J'ai trouvé par la suite qu'il était en train d'évaluer correctement le DataTrigger tout au long. Je pensais que ce n'était pas parce que mon contrôle n'était pas visible à l'exécution, mais j'ai découvert que c'était à cause d'une erreur dans mon XAML (j'ai oublié une propriété Grid.Column, donc un contrôle en chevauchait un autre).

Désolé pour la question déroutante.

Edit # 3

est ici un code d'application de la console montrant la situation juste pour Jon :)

class Program 
{ 
    static void Main(string[] args) 
    { 
     object value; 
     value = Test.Value1; 

     // Put breakpoint here 
     // Run ?(int)value vs Convert.ToInt32(value) in the immediate window 
     // Why does the first return Value1 while the 2nd returns 1? 
     Console.ReadLine(); 
    } 
} 

public enum Test 
{ 
    Value1 = 1 
} 
+0

Pouvez-vous coller un exemple de travail du code? –

+1

Est-ce que vous le mettez dans une chaîne? Est-ce que vous le lancez dans un Console.WriteLine()? Je ne vois pas le même problème. Casting à un int semble me donner le comportement attendu. –

+0

Quelque chose d'autre se passe. 'object o = MyEnum.Blah; int i = (int) o; 'définit' i' à la valeur entière du membre de l'énumération. – dlev

Répondre

11

On dirait que vous êtes dupés par la fenêtre immédiate. On ne sait pas exactement ce que vous avez fait dans la fenêtre immédiate, mais je peux dire avec certitude absolue que si vous lancez un int vous ne pas obtenir un retour string. Le système de type complètement empêche que cela se produise.

+0

Vous avez raison, la valeur est correcte dans la sortie, mais pas dans la fenêtre immédiate. Bon à savoir que je ne devrais pas aveuglément faire confiance à la fenêtre immédiate. (J'ai eu une erreur dans mon XAML qui me faisait penser que le convertisseur retournait toujours faux car un contrôle n'était pas visible) – Rachel

+0

Et j'écrivais '? ((Int) paramètre)' dans la fenêtre Exécution et il retournait 'Value1 '. Exécuter '? System.Convert.ToInt32 (paramètre)' renvoyait correctement '1' – Rachel

+0

@Rachel: Hmm ... ne peut même pas reproduire cela.Mais je n'utilise que très rarement la fenêtre immédiate pour commencer :) –

1

Il est techniquement impossible ce que vous décrivez ici. Ce que vous voyez est le membre NAME de l'énumération qui est montré par le débogueur. Pensez à ce genre de "syntaxe sugare". Donc le vrai problème à mon humble avis, c'est que juste pour ints ne sont pas égaux.

Pour vérifier ceci:

Lisez votre « string », Check entier affecté à l'énumération déclarée et ceck si entier est égal à fait à ce que vous obtenez comme un paramètre dans la fonction.

0

J'ai exécuté cet exemple de code dans l'oubli, et je le trouve pour retourner false chaque fois parce que le value is int échoue. La valeur est un objet, pas un nombre entier.

+0

La valeur d'exécution de 'parameter' est une Enum – Rachel

+0

Oui. J'ai corrigé ma déclaration. C'est ce que vous obtenez lorsque vous copiez/collez. :) –

0

J'imagine ce qui se passe est que votre object parameter est à venir en tant que valeur string et donc votre appel à

if (parameter.GetType().IsEnum && value is int) 

est faux et vous sauter le corps et return false directement. À la place, utilisez Enum.Parse() ou Convert.ToInt32() pour remplacer la chaîne par la valeur enum ou la valeur int, puis comparez.

+0

Non, les deux propriétés dans cette déclaration évaluent à vrai – Rachel

+0

Pas de soucis, était une supposition basée sur les données à la fois. –

1

Votre question est vraiment "pourquoi" et non "comment", je le réalise.

Cependant, voici comment:

enum Options : int { one = 1, two = 2, three = 3 } 
public MainWindow() 
{ 
    InitializeComponent(); 

    object _Option = Options.three; 

    // shows "three" 
    MyTextBox.Text = ((Options)_Option).ToString(); 

    // shows "3" 
    MyTextBox.Text = ((int)((Options)_Option)).ToString(); 
}