2009-05-17 11 views
7

मैंने डबल से पूर्णांक में कनवर्ट करने के लिए एक कनवर्टर बनाया है।मेरा कनवर्टर अमान्य कास्ट त्रुटि क्यों देता है?

लेकिन रेखा "वापसी (int) मान;" हमेशा "निर्दिष्ट कास्ट वैध नहीं है" मिलता है।

मुझे ऐसा करने के लिए क्या करना है ताकि मेरा कनवर्टर सफलतापूर्वक एक डबल रूपांतरित हो और एक पूर्णांक वापस भेज सके?

कनवर्टर:

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> 

उत्तर

8

आप (परिवर्तित नहीं) डबल से कास्ट करने के लिए int करने के लिए प्रयास कर रहे हैं, जो काम नहीं करेगा। आपको एक निहित रूपांतरण करने की आवश्यकता है या Convert.ToInt32() का उपयोग करें - क्योंकि तर्क वास्तव में प्रकार ऑब्जेक्ट का है, मुझे लगता है कि आपको कंपाइलर को खुश रखने के लिए बाद वाले की आवश्यकता होगी। यह आप पर निर्भर करता है कि आप संस्कृति के प्रारूप प्रदाता को शामिल करना चाहते हैं या नहीं।

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

आप, कि है, वस्तु की एक ही आकार है जब डाली ऑपरेटर का उपयोग कर सकते हैं जब एक ऑब्जेक्ट प्रकार का एक उदाहरण है जो आप कास्ट कर रहे हैं के लिए है। उदाहरण के लिए, यदि कक्षा Foo कक्षा बार को बढ़ाता है, तो आप बार टाइप करने के लिए Foo प्रकार के ऑब्जेक्ट को ऑब्जेक्ट कर सकते हैं - क्योंकि Foo ऑब्जेक्ट में सभी ऑब्जेक्ट्स और गुण होते हैं जो एक बार ऑब्जेक्ट होता है। हालांकि, आप फू टाइप करने के लिए टाइप बार का ऑब्जेक्ट नहीं डाल सका क्योंकि फू बदलता है (या जहां तक ​​कंपाइलर का संबंध है, बदल सकता है) बार बार, विधियों या गुणों को जोड़कर, जो एक बार ऑब्जेक्ट ' टी है

अपने मामले में आप आदिम प्रकारों से निपट रहे हैं जो केवल ऑब्जेक्ट इंटरफ़ेस साझा करते हैं - उनके बीच विरासत संबंध नहीं है, सिवाय इसके कि वे दोनों ऑब्जेक्ट से प्राप्त होते हैं। हालांकि, दोनों के बीच एक अंतर्निहित रूपांतरण है। आप किसी ऑब्जेक्ट को एक प्रकार के चर के लिए एक प्रकार असाइन कर सकते हैं, हालांकि आप मान में कुछ सटीकता खो सकते हैं।

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 

हालांकि, आप एक प्रकार की वस्तु को दूसरे प्रकार में नहीं डाल सकते हैं। कास्टिंग का तात्पर्य है कि आप ऑब्जेक्ट का उपयोग करेंगे जैसे कि यह अन्य प्रकार के थे। इस मामले में आकार भिन्न हैं और यह नहीं किया जा सकता है।

+0

यदि पैरामीटर हमेशा वापसी (int) (डबल) मान से दोगुना होता है; काम भी करेगा, लेकिन ToInt32 बेहतर है। – Nir

+0

@Nir - हां, यह संकलक को दोहरे से int तक एक अंतर्निहित रूपांतरण करने की अनुमति देगा, भले ही यह एक कलाकार की तरह दिखता हो। – tvanfosson

3

समस्या यह है कि आप एक ही समय में एक अनबॉक्स और कलाकार दोनों को करने का प्रयास कर रहे हैं। यह असफल हो जाएगा। आपको पहले अनबॉक्स होना चाहिए और फिर उपयुक्त प्रकार पर डालना होगा।

return (int)(double)value; 

एरिक लिपर्ट हाल ही में एक अच्छा लेख लिखा है कि यह आवश्यक क्यों है। यह

1

double मूल्य एक वस्तु के अंदर बॉक्सिंग पढ़ने लायक है, और यह बाहर निकलने के लिए एक ही रास्ता एक double के रूप में यह Unbox है। इसके बाद आप इसे int पर डाल सकते हैं।

return (int)(double)value; 

तुम भी Convert.ToInt32(object) विधि (के रूप में tvanfosson सुझाव दिया) है, जो IConvertible करने के लिए वस्तु डाली और कॉल यह आभासी ToInt32 विधि, जो बारी में Convert.ToInt32(double) विधि कॉल करेंगे होगा उपयोग कर सकते हैं। यह निश्चित रूप से थोड़ा अधिक ओवरहेड है।

1

आप कन्वर्ट करना चाहते हैं लेकिन आप डबल से int तक कास्टिंग कर रहे हैं। इसे आज़माएं:

public object Convert(object value, ...) 
    { 
     return (int)(double)value; 
    } 
संबंधित मुद्दे