2010-12-21 8 views
3

Ich habe ein Problem mit dem folgenden Code bekommen (die aber Abstürze kompilieren):C# implizite Umwandlung „Überlastung“ und Reflexion Problem

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 

namespace ConsoleApplication1 
{ 
    public struct MyBoolean 
    { 
     public bool Value { get; set; } 

     //cast string -> MyBoolean 
     public static implicit operator MyBoolean(System.String value) 
     { 
      return new MyBoolean() { Value = (value[0] == 'J') }; 
     } 

     //cast bool -> MyBoolean 
     public static implicit operator MyBoolean(bool value) 
     { 
      return new MyBoolean() { Value = value }; 
     } 

     //cast MyBoolean -> bool 
     public static implicit operator bool(MyBoolean value) 
     { 
      return value.Value; 
     } 
    } 

    public class Foo 
    { 
     public MyBoolean TestProp { get; set; } 
    } 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      MyBoolean myBool = true;  //works 

      myBool = "N"; //works 

      Foo foo = new Foo(); 
      foo.TestProp = "J";    //works 

      PropertyInfo pi = foo.GetType().GetProperty("TestProp"); 

      var obj = Convert.ChangeType("J", typeof(MyBoolean));  //throws an InvalidCastException 

      pi.SetValue(foo, "J", null);  //throws an ArgumentException 

     } 
    } 
} 

Ich habe die Aussagen kommentiert, die nicht funktionieren. Weiß jemand, warum Convert.ChangeType und PropertyInfo.SetValue nicht den "überladenen" Darstellungsoperator zu verwenden scheint, wie in MyBoolean definiert?

Übrigens habe ich hier schon einige andere Dokumente durchgelesen, aber ich fand keine genaue Übereinstimmung des Problems.

Mit freundlichen Grüßen Thomas

Antwort

0

Versuchen IConvertible implementieren. Convert konvertiert Ihre Instanz zu dieser Schnittstelle, um eine Konvertierung durchzuführen.

Wie bei PropertyInfo.SetValue wird die Set-Methode der Eigenschaft abgerufen. Wenn diese Methode über Reflection, AFAICT, aufgerufen wird, werden die Argumente nach Typ und nicht nach der Möglichkeit, implizit in den richtigen Typ umgewandelt zu werden, überprüft. Dieser Cast muss vor dem Aufruf ausgeführt werden.

8

Convert.ChangeType() verwendet keine impliziten Operatoren. Sie müssen Ihren MyBoolean-Typ implementieren IConvertible.

Das zweite Problem ist verwandt. Benutzerdefinierte Konvertierungsoperatoren werden nicht verwendet. Sie müssen es manuell konvertieren, bevor Sie es an SetValue() übergeben.

+0

danke, siride für Ihre Erklärung. Jetzt habe ich meine Requisiten zurück auf bool (von MyBoolean) geändert und sie mit Attributen versehen, so dass ich diese Requisiten vor dem Aufruf von SetValue manuell vorspielen kann. – Thomas

+0

Stellen Sie sicher, dass Sie meine Antwort dann als die richtige auswählen. – siride