I have a property of type object
, which contains an Enum
value, and when I cast it using (int)value
, it returns a string
of the Enum's name. Why?
The code where I noticed this is in this answer. Using Convert.ToInt32()
correctly casts the Enum
to an int
, but I was just curious why I would get a string back when using (int)
. It doesn't even throw me an error.
Edit
Here's a quick sample. I commented where I put the breakpoint, and was using the immediate window to determine what the output was.
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&g开发者_StackOverflowt;
Edit #2
Just hoping to clear up some confusion...
I said it was returning a string because running ?((int)parameter)
in the Immediate Window was returning the enum name, while running ?System.Convert.ToInt32(parameter)
was correctly displaying the int.
I found afterwards that it was actually evaluating correctly to the DataTrigger all along. I thought it wasn't because my control wasn't visible at runtime, however I discovered that was because of an error in my XAML (I forgot a Grid.Column
property, so one control was overlapping another).
Sorry for the confusing question.
Edit #3
Here's some console app code demonstrating the situation just for 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
}
It sounds like you're being duped by the Immediate Window. It's not clear exactly what you did in the Immediate Window, but I can say with absolute certainty that if you cast to an int
you do not get a string
back. The type system completely prevents that from happening.
It's technically impossible what you describe here. What you see is the NAME of enumeration member which is shown by debugger. Think of this like kind of "syntax sugare". So the real problem IMHO, is that just to ints are not equal.
To check this:
Read your "string", Check integer assigned to in enumeration declared, and ceck if integer actually equals to that one you get like a parameter in the function.
Your question is really "why" and not "how", I realize that.
However, here's how:
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();
}
I've run this code sample into oblivion, and I'm finding it to return false each time because the value is int
is failing. value is an object, not an integer.
I imagine what is happening is that your object parameter
is coming in as a string
value and thus your call to
if (parameter.GetType().IsEnum && value is int)
is false and you skip the body and return false
directly.
Instead, use Enum.Parse() or Convert.ToInt32() to change the string into either the enum value or the int value and then compare.
精彩评论