none
Objekt-Wert in typisierten Wert verwandeln... RRS feed

  • Frage

  • Salü zäme
    Ich habe einen Wert als Objekt (object) und kenne den Type (Type-Klasse). Nun möchte ich diesen Wert addieren. Dazu müsste ich den Objekt-Wert wieder in einen Typen-Wert (z.B. Integer, Double) verwandeln können.
    Weiss jemand, wie man dies tun kann? Oder muss ich mit einer Switch-Abfrage, alle Typen, gemäss den Angaben von GetType() unterscheiden: Was ja recht mühsam und unschön wäre.

    Danke für eure Hinweise und Gruss
    Jakob Brunner


    Jakob Brunner, Switzerland
    Samstag, 11. Dezember 2010 09:25

Antworten

  • Hallo Jakob,

    Wenn Du eine Zuweisung hast wie z.B.: object a = 1 dann ist der System.RuntimeType von a System.Int32. Du kannst einen Operanden wie + aber trotzdem nicht direkt auf ein object anwenden (wg. Typprüfung zur Kompilierzeit). D.h. entweder du konvertierst/castest das Objekt, oder Du verwendest das Schlüsselwort dynamic, womit die Typauflösung erst zur Laufzeit geschieht.

    using System;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
          dynamic a = 1; //oder 1.5
          dynamic b = 2;
    
          dynamic c = Add(a, b); // oder a + b
    
          Console.WriteLine(c);
          Console.ReadKey(true);
        }
    
        static dynamic Add(dynamic a, dynamic b)
        {
          return a + b;
        }
      }
    }
    
    

    dynamic (C#-Referenz):
    http://msdn.microsoft.com/de-de/library/dd264741.aspx

    Gruß
    Marcel

    Samstag, 11. Dezember 2010 10:21
    Moderator
  • Hallo Jakob,

    gut, das ist das alte Thema IAritmetic-Schnittstelle [Wunsch].

    Möglichkeiten gibt es neben dynamic je nach Anforderung u.a. auch über Lambda-Expressions:

      object obj1 = (double)39.5;
      object obj2 = (double)2.5;
      // die obige Typen müssen dann den binären Operator Add definieren
      object result;
      try
      {
      result = Expression.Lambda<Func<object>>(
       Expression.Convert(Expression.Add(
       Expression.Constant(obj1), Expression.Constant(obj2)),
       typeof(object))).Compile()();
      }
      catch (Exception exp)
      {
      MessageBox.Show(exp.Message);
      return; // oder Dein Fehlerhandling
      }
      MessageBox.Show("Ergebnis: " + result);
    
    
    Natürlich auch Deine angesprochene switch-Abfrage.
    

    ciao Frank
    Samstag, 11. Dezember 2010 10:35
  • Am 11.12.2010 10:25, schrieb Jakob.Brunner:

    Salü zäme
    Ich habe einen Wert als Objekt (object) und kenne den Type (Type-Klasse). Nun möchte ich diesen Wert addieren. Dazu müsste ich den Objekt-Wert wieder in einen Typen-Wert (z.B. Integer, Double) verwandeln können.
    Weiss jemand, wie man dies tun kann? Oder muss ich mit einer Switch-Abfrage, alle Typen, gemäss den Angaben von GetType() unterscheiden: Was ja recht mühsam und unschön wäre.

    Hallo

    Prüfe auf die Typen, die Du erwartest,

    class Test()
    {
    
      private double _dval = 0;
      private int _ival = 0;
    
      void Add (object valueToAdd)
      {
        if (valueToAdd is double)
          _dval += (double) valueToAdd;
        else if (valueToAdd is int)
          _ival += (int) valueToAdd;
        //more types to handle
        else
          throw new ArgumentException("valueToAdd",
            "expected numeric value of type int or double");
      }
    }
    lass die anderen einfach außen vor bzw. wirf'
    eine Exception bei unerwarteten Typen.

     


     Christoph

    Samstag, 11. Dezember 2010 13:17

Alle Antworten

  • Hallo Jakob,

    Wenn Du eine Zuweisung hast wie z.B.: object a = 1 dann ist der System.RuntimeType von a System.Int32. Du kannst einen Operanden wie + aber trotzdem nicht direkt auf ein object anwenden (wg. Typprüfung zur Kompilierzeit). D.h. entweder du konvertierst/castest das Objekt, oder Du verwendest das Schlüsselwort dynamic, womit die Typauflösung erst zur Laufzeit geschieht.

    using System;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
          dynamic a = 1; //oder 1.5
          dynamic b = 2;
    
          dynamic c = Add(a, b); // oder a + b
    
          Console.WriteLine(c);
          Console.ReadKey(true);
        }
    
        static dynamic Add(dynamic a, dynamic b)
        {
          return a + b;
        }
      }
    }
    
    

    dynamic (C#-Referenz):
    http://msdn.microsoft.com/de-de/library/dd264741.aspx

    Gruß
    Marcel

    Samstag, 11. Dezember 2010 10:21
    Moderator
  • Hallo Jakob,

    gut, das ist das alte Thema IAritmetic-Schnittstelle [Wunsch].

    Möglichkeiten gibt es neben dynamic je nach Anforderung u.a. auch über Lambda-Expressions:

      object obj1 = (double)39.5;
      object obj2 = (double)2.5;
      // die obige Typen müssen dann den binären Operator Add definieren
      object result;
      try
      {
      result = Expression.Lambda<Func<object>>(
       Expression.Convert(Expression.Add(
       Expression.Constant(obj1), Expression.Constant(obj2)),
       typeof(object))).Compile()();
      }
      catch (Exception exp)
      {
      MessageBox.Show(exp.Message);
      return; // oder Dein Fehlerhandling
      }
      MessageBox.Show("Ergebnis: " + result);
    
    
    Natürlich auch Deine angesprochene switch-Abfrage.
    

    ciao Frank
    Samstag, 11. Dezember 2010 10:35
  • Am 11.12.2010 10:25, schrieb Jakob.Brunner:

    Salü zäme
    Ich habe einen Wert als Objekt (object) und kenne den Type (Type-Klasse). Nun möchte ich diesen Wert addieren. Dazu müsste ich den Objekt-Wert wieder in einen Typen-Wert (z.B. Integer, Double) verwandeln können.
    Weiss jemand, wie man dies tun kann? Oder muss ich mit einer Switch-Abfrage, alle Typen, gemäss den Angaben von GetType() unterscheiden: Was ja recht mühsam und unschön wäre.

    Hallo

    Prüfe auf die Typen, die Du erwartest,

    class Test()
    {
    
      private double _dval = 0;
      private int _ival = 0;
    
      void Add (object valueToAdd)
      {
        if (valueToAdd is double)
          _dval += (double) valueToAdd;
        else if (valueToAdd is int)
          _ival += (int) valueToAdd;
        //more types to handle
        else
          throw new ArgumentException("valueToAdd",
            "expected numeric value of type int or double");
      }
    }
    lass die anderen einfach außen vor bzw. wirf'
    eine Exception bei unerwarteten Typen.

     


     Christoph

    Samstag, 11. Dezember 2010 13:17