Perché il mio convertitore di dare un cast non valido errore?
-
22-08-2019 - |
Domanda
Ho creato un Convertitore per la conversione da doppia per intero.
Ma il "return (int)valore;" ottiene sempre un "cast specificato non è valido."
Cosa devo fare perché la mia Converter converte con successo una doppia e restituisce un numero intero?
Converter:
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
}
}
XAML:
<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>
Soluzione
Si sta tentando di lanciare (non convertire) dal doppio a int, che non funziona. Hai bisogno di fare una conversione implicita o utilizzare Convert.ToInt32 () - dal momento che l'argomento è in realtà di tipo di oggetto Penso che sarà necessario a quest'ultimo di mantenere il compilatore felice. E 'a voi decidere se si desidera includere provider di formato la propria cultura o meno.
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Convert.ToInt32(value);
}
È possibile utilizzare l'operatore di cast quando l'oggetto sono la stessa forma , cioè quando un oggetto è un'istanza del tipo a cui si sta casting. Ad esempio, se la classe Foo estende la classe Bar, allora si può lanciare un oggetto di tipo Foo digitare Bar - perché un oggetto Foo ha tutti i metodi e le proprietà che un oggetto bar sarebbe. Non si poteva, tuttavia, lanciare un oggetto di tipo bar a digitare Foo Foo perché cambia (o può cambiare, per quanto riguarda il compilatore è interessato) il forma di Bar, con l'aggiunta di metodi o proprietà che un oggetto Bar non ha.
Nel tuo caso si tratta di tipi primitivi che condividono solo l'interfaccia oggetto - non c'è una relazione di ereditarietà tra loro, tranne che entrambi derivano da oggetto. V'è, tuttavia, un implicito conversione tra i due. È possibile assegnare un oggetto un tipo di una variabile dell'altro, anche se si rischia di perdere una certa precisione nel valore.
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
Non è possibile, però, lanciare un oggetto di un tipo all'altro. Casting implica che si prevede di utilizzare l'oggetto come se fosse di altro tipo. In questo caso i forme sono diverse e non può essere fatto.
Altri suggerimenti
Il problema è che si sta tentando di fare entrambe le cose un Unbox e un cast al tempo stesso. Questo fallirà. È necessario prima Unbox e poi gettato al tipo appropriato.
return (int)(double)value;
Eric Lippert ha scritto di recente un bell'articolo su esattamente il motivo per cui ciò sia necessario. Vale la pena di lettura
Il double
il valore è in scatola all'interno di un oggetto, e l'unico modo per uscire è quello di unbox come un double
.Dopo di che è possibile eseguire il cast di un int
.
return (int)(double)value;
È inoltre possibile utilizzare il Convert.ToInt32(object)
metodo (come tvanfosson suggerito), che sarà il cast dell'oggetto IConvertible e chiamata virtuale ToInt32
il metodo, che a sua volta chiama il Convert.ToInt32(double)
metodo.Che è, naturalmente, un po ' più alto.
Si desidera convertire, ma si sta facendo lanciare da doppia a int. Prova questo:
public object Convert(object value, ...)
{
return (int)(double)value;
}