C# 为什么我的转换器出现无效转换错误?

C# 为什么我的转换器出现无效转换错误?,c#,wpf,xaml,casting,converters,C#,Wpf,Xaml,Casting,Converters,我创建了一个转换器,将double转换为integer 但行“return(int)value;”始终获取“指定的强制转换无效” 为了使转换器成功地转换一个double并发回一个整数,我必须做些什么 转换器: namespace TestChangeAngle { [ValueConversion(typeof(double), typeof(int))] class DoubleToIntegerConverter : IValueConverter {

我创建了一个转换器,将double转换为integer

但行“return(int)value;”始终获取“指定的强制转换无效”

为了使转换器成功地转换一个double并发回一个整数,我必须做些什么

转换器:

namespace TestChangeAngle
{
    [ValueConversion(typeof(double), typeof(int))]
    class DoubleToIntegerConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (int)value;
        }

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

        #endregion
    }
}
<Page x:Class="TestChangeAngle.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestChangeAngle"
    Title="Page1">
    <Page.Resources>
        <local:DoubleToIntegerConverter x:Key="DoubleToIntegerConverter"/>
    </Page.Resources>

    <StackPanel HorizontalAlignment="Left" Margin="20">
        <Image Source="images\logo2.png" 
               RenderTransformOrigin="0.5, 0.5"
               Width="100" 
               Margin="10">
            <Image.RenderTransform>
                <RotateTransform Angle="{Binding ElementName=TheSlider, Path=Value}"/>
            </Image.RenderTransform>
        </Image>
        <Slider x:Name="TheSlider"
                Width="200" 
                Minimum="0"
                Maximum="360"
                HorizontalAlignment="Center"
                Margin="10" 
                Cursor="Hand"/>
        <TextBox x:Name="TheAngle"
                 Margin="10"
                 Width="100">
            <TextBox.Text>
                <Binding ElementName="TheSlider"
                         Path="Value"
                         UpdateSourceTrigger="PropertyChanged"
                         Converter="{StaticResource DoubleToIntegerConverter}"
                         Mode="TwoWay">
                    <Binding.ValidationRules>
                        <local:MinMaxValidationRule Minimum="0" Maximum="360"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>

    </StackPanel>
</Page>
XAML:

namespace TestChangeAngle
{
    [ValueConversion(typeof(double), typeof(int))]
    class DoubleToIntegerConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (int)value;
        }

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

        #endregion
    }
}
<Page x:Class="TestChangeAngle.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestChangeAngle"
    Title="Page1">
    <Page.Resources>
        <local:DoubleToIntegerConverter x:Key="DoubleToIntegerConverter"/>
    </Page.Resources>

    <StackPanel HorizontalAlignment="Left" Margin="20">
        <Image Source="images\logo2.png" 
               RenderTransformOrigin="0.5, 0.5"
               Width="100" 
               Margin="10">
            <Image.RenderTransform>
                <RotateTransform Angle="{Binding ElementName=TheSlider, Path=Value}"/>
            </Image.RenderTransform>
        </Image>
        <Slider x:Name="TheSlider"
                Width="200" 
                Minimum="0"
                Maximum="360"
                HorizontalAlignment="Center"
                Margin="10" 
                Cursor="Hand"/>
        <TextBox x:Name="TheAngle"
                 Margin="10"
                 Width="100">
            <TextBox.Text>
                <Binding ElementName="TheSlider"
                         Path="Value"
                         UpdateSourceTrigger="PropertyChanged"
                         Converter="{StaticResource DoubleToIntegerConverter}"
                         Mode="TwoWay">
                    <Binding.ValidationRules>
                        <local:MinMaxValidationRule Minimum="0" Maximum="360"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>

    </StackPanel>
</Page>

您正试图将double转换为int(而不是转换),但这不起作用。您需要执行隐式转换或使用Convert.ToInt32()——因为参数实际上是object类型的,所以我认为您需要后者来让编译器满意。是否包含区域性的格式提供程序取决于您

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    return Convert.ToInt32(value);
}
当对象的形状相同时,也就是说,当一个对象是要对其进行强制转换的类型的实例时,可以使用“强制转换”操作符。例如,如果类Foo扩展了类Bar,那么可以将Foo类型的对象强制转换为Bar类型,因为Foo对象具有Bar对象所具有的所有方法和属性。但是,您不能将Bar类型的对象强制转换为Foo类型,因为Foo通过添加Bar对象没有的方法或属性来更改(或者可以更改,就编译器而言)Bar的形状

在您的例子中,您处理的是只共享对象接口的基本类型——它们之间没有继承关系,只是它们都派生自对象。然而,这两者之间存在一种隐式的转换。可以将一个对象的一种类型指定给另一种类型的变量,但该值可能会失去一些精度

double x = 1.1;
int y = 0;

y = x;  // implicit conversion, this works, y will be 1
x = y;  // implicit conversion, this works, x will be 1.0

但是,不能将一种类型的对象强制转换为另一种类型。强制转换意味着您将像使用其他类型的对象一样使用该对象。在这种情况下,形状不同,无法执行此操作。

问题在于您试图同时执行取消装箱和强制转换。这将失败。您必须首先取消装箱,然后强制转换为适当的类型

return (int)(double)value;
埃里克·利珀特(Eric Lippert)最近写了一篇很好的文章,阐述了为什么这是必要的。值得一读


double
值装箱到对象中,将其取出的唯一方法是将其作为
double
解除装箱。之后,您可以将其强制转换为
int

return (int)(double)value;

您还可以使用
Convert.ToInt32(object)
方法(正如tvanfosson建议的那样),该方法将对象强制转换为IConvertible,并调用其虚拟
ToInt32
方法,该方法反过来将调用
Convert.ToInt32(double)
方法。这当然会增加一些开销。

您想要转换,但您正在从double转换为int。 试试这个:

    public object Convert(object value, ...)
    {
        return (int)(double)value;
    }

如果参数始终是双精度返回(int)(double)值;也可以,但ToInt32更好。@Nir--是的,这将允许编译器执行从double到int的隐式转换,即使它看起来像一个强制转换。