3 Stimmen

Warum gibt das Casting einer in einem Objekt gespeicherten Aufzählung in einen int einen String zurück?

Ich habe eine Eigenschaft vom Typ object die eine Enum Wert, und wenn ich ihn mit (int)value gibt es eine string des Namens der Enum. Warum?

Der Code, bei dem mir dies aufgefallen ist, befindet sich in diese Antwort . Verwendung von Convert.ToInt32() wirft korrekt die Enum zu einer int aber ich war nur neugierig, warum ich einen String zurückbekomme, wenn ich (int) . Es wird nicht einmal eine Fehlermeldung ausgegeben.

bearbeiten

Hier ist ein kurzes Beispiel. Ich habe kommentiert, wo ich den Haltepunkt gesetzt habe, und habe das unmittelbare Fenster verwendet, um festzustellen, was die Ausgabe war.

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>

Bearbeiten #2

Ich hoffe nur, dass ich einige Unklarheiten beseitigen kann...

Ich sagte, dass es eine Zeichenkette zurückgibt, weil die Ausführung ?((int)parameter) im Sofort-Fenster gab den Enum-Namen zurück, während die ?System.Convert.ToInt32(parameter) den Wert int korrekt anzeigt.

Im Nachhinein stellte ich fest, dass der DataTrigger die ganze Zeit über korrekt ausgewertet wurde. Ich dachte, dass es nicht daran lag, dass mein Steuerelement zur Laufzeit nicht sichtbar war, aber ich entdeckte, dass dies an einem Fehler in meiner XAML lag (ich vergaß ein Grid.Column Eigenschaft, so dass sich ein Steuerelement mit einem anderen überlappt).

Entschuldigung für die verwirrende Frage.

Bearbeiten #3

Hier ist einige Konsole app Code demonstriert die Situation nur für 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
}

11voto

Jon Skeet Punkte 1325502

Es hört sich so an, als würden Sie von dem Sofortfenster überlistet werden. Es ist nicht klar, was genau Sie hat im Fenster "Sofort", aber ich kann mit Sicherheit sagen absolut die Gewissheit, dass, wenn Sie einen Wurf auf eine int Sie tun no bekommen eine string zurück. Das Typensystem vollständig verhindert dies.

1voto

Tigran Punkte 60618

Es ist technisch unmöglich, was Sie hier beschreiben. Was Sie sehen, ist der NAME des Aufzählungsmitglieds, der vom Debugger angezeigt wird. Stellen Sie sich dies als eine Art "Syntax-Sugare" vor. Also das eigentliche Problem IMHO, ist, dass nur zu ints nicht gleich sind.

Um dies zu überprüfen:

Lesen Sie Ihre "Zeichenfolge", Prüfen Sie Integer in Aufzählung zugewiesen deklariert, und ceck, wenn Integer tatsächlich gleich, dass man wie ein Parameter in der Funktion zu erhalten.

1voto

Jerry Nixon Punkte 30239

Ihre Frage ist eigentlich "warum" und nicht "wie", das ist mir klar.

Aber so geht's:

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();
}

0voto

John Kraft Punkte 6676

Ich habe dieses Codebeispiel in Vergessenheit geraten lassen, und ich finde, dass es jedes Mal false zurückgibt, weil die value is int scheitert. value ist ein Objekt, keine ganze Zahl.

0voto

James Michael Hare Punkte 36545

Ich stelle mir vor, dass Ihr object parameter kommt als string Wert und damit Ihr Aufruf an

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

falsch ist und man den Körper überspringt und return false direkt.

Verwenden Sie stattdessen Enum.Parse() oder Convert.ToInt32(), um die Zeichenkette entweder in den Enum-Wert oder den Int-Wert umzuwandeln und dann zu vergleichen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X