2009-06-23 9 views
6

Wie wird ein Objekt (vom Typ Object) in seinen realen Typ umgewandelt?Wie wird ein Objekt in seinen Typ umgewandelt?

Ich brauche etwas wie dieses

Myobject [i] += Myobject [j]; 

myObject der Art zu tun, ist Gegenstand. Mein Objekt [i] und mein Objekt [j] sind immer vom selben Typ.

myObject [i] .Gettype() würde ich die Art ... aber wie würde ich werfe das Objekt tatsächlich in diese Art dem ‚+‘ Operator

+0

Worin wird das MyObject-Array als deklariert? – ChrisF

+0

Ist der '+' Operator für den Typ von 'MyObject' definiert? – Groo

+0

object [] Myobject –

Antwort

16

Ich gehe davon aus, die zusätzlich (+ auszuführen) Operator ist für Ihren benutzerdefinierten Typ definiert (MyType in diesem Beispiel).

Wenn ja, müssen Sie einfach die LHS und RHS der Zuordnung zu werfen. Dies ist erforderlich, da beide Operanden zur Kompilierungszeit bekannte Typen sein müssen, um die richtige Operatorüberladung auszuwählen. Dies ist für statische Sprachen erforderlich, obwohl dynamische Sprachen (möglicherweise C# 4.0) dies beheben können.

((MyType)Myobject[i]) += (MyType)Myobject[j]; 

Update:

Einige Reflexion Magie, um dieses Problem in C# 2.0/3.0 (mit einem Mangel an dynamischer Typisierung) erhalten können.

public static object Add(object a, object b) 
{ 
    var type = a.GetType(); 
    if (type != b.GetType()) 
     throw new ArgumentException("Operands are not of the same type."); 

    var op = type.GetMethod("op_Addition", BindingFlags.Static | BindingFlags.Public); 
    return op.Invoke(null, new object[] { a, b }); 
} 

Beachten Sie, dass dies funktioniert nur für nicht-primitive Typen. Für primitive Typen wie int, float usw. müssten Sie eine switch-Anweisung für den Typ hinzufügen, der die Operanden manuell umsetzt und den Additionsoperator anwendet. Dies liegt daran, dass Operatorüberladungen nicht wirklich für primitive Typen definiert sind, sondern in der CLR integriert sind.

Wie auch immer, hoffe, dass das Ihr Problem löst.

+0

Ich weiß nicht, Art von "MyType" zur Kompilierzeit –

+1

Hmmm, das macht Dinge kompliziert ... – Noldorin

+0

Siehe meine aktualisierte Antwort und auch Marc Kommentare auf sein Beitrag. – Noldorin

1

Wenn Myobject ist ein Array dann

Myobject [i] += Myobject [j]; 

sollte so lange arbeiten, wie der + Operator hat für die Art definiert.

Als Myobject ist vom Typ Gegenstand dieser mit dem Fehler fehl:

Operator '+' cannot be applied to operands of type 'object' and 'object'

Um den Typen zur Laufzeit (ein konstruiertes Beispiel) zu erhalten:

double a = 1.0; 
double b = 2.0; 

object a1 = a; 
object b1 = b; 

Type ta = a1.GetType(); 
Type tb = b1.GetType(); 

ta und tb sind auf " Doppelt".

UPDATE:

Ein Wort der Warnung im Voraus - was ich bin, ist sehr plump vorschlagen (gelinde gesagt)

Wenn Sie eine endliche Anzahl von Arten und sind die Typen garantiert gleich zu sein.Wenn ja, könnten Sie Folgendes tun:

Type test = Myobject[i].GetType(); 
if (test.Equals(typeof(double))) 
{ 
    (double)Myobject[i] += (double)Myobject[j]; 
} 

und so weiter.

Wenn die Typen nicht die gleichen sind, dann ist es ein bisschen komplizierter.

Wenn Sie eine unbekannte Anzahl von Typen bekommen haben, dann werden Sie für C# 4.

warten müssen Oder Sie könnten mit Reflexion tun wie Noldorin vermuten lässt.

8

Ist der Typ zur Kompilierzeit bekannt?

C# unterstützt (bis C# 4.0) keine Operatoren für andere als bekannte, feste Typen.

Sie können Operatoren mit Generika über ein paar Tricks verwenden - like so. Lassen Sie uns wissen, wenn Generika ein Faktor hier ist (ich ausführlich auf reden kann ...)

In 4.0, die Sie verwenden können:

dynamic x = MyObject[i]; 
x += MyObject[j]; 
MyObject[i] = x; 

Die Verwendung von dynamic verursacht Magie viel passieren ;-p

Andere als diese beiden Szenarien, müssen Sie ihren Typ zur Kompilierzeit wissen, oder tun Sie eine Los der Arbeit.

+0

Magie hält die Welt in Bewegung. –

+0

Typ wäre ein numerischer Typ. es könnte float, double, integer oder irgendwas sein –

+0

Das ändert leider nichts. Der Trick "Generika" ist wahrscheinlich Ihre beste Wette, aber das erfordert ein Typen-Array. Sie können MakeGenericMethod verwenden, um von "object" zu dem generischen Operatorcode zu wechseln, aber es wird nicht hübsch sein. Und MakeGenericMethod ist langsam ('dynamic' wäre besser, wenn es freigegeben wird). –

0

Es ist immer besser, Boxen und Unboxing zu vermeiden und direkte Typen zu verwenden. Ich kenne nicht all Ihren Hintergrund, aber vielleicht ist es besser, Array zu reellen Typ zu wechseln oder generische Liste zu verwenden?

MyType[] array = new MyType[x]; 

oder

List<MyType> list = new List<MyType>(); 
0

Ich werde vorschlagen, eine swicth Anweisung, wie der Typ ein numerischer sein würde. An jedem Zweig, könnten Sie Ihre Zahlen zu temporären Variablen werfen und den Betrieb wie ausführen:

switch (Myobjetc[j].GetType()) 
    { 
     case typeof(short):     
      break; 
     case typeof(int): 
      int a, b = 0; 
      a = (int)Myobjet[i]; 
      b = (int)Myobject[j]; 
      a += b; 
      break; 
     case typeof(long): 
      break; 
     case typeof(decimal): 
      break; 
     case typeof(double): 
      break; 
     case typeof(float): 
      break;    
     default: 
      break; 
    } 
+2

Außer dass Schalter (obj.GetType()) nicht kompiliert - "Ein Wert eines ganzzahligen Typs erwartet " – ChrisF

+0

ersetzt 'switch' mit 'if' würde tun ... erfordert etwas Arbeit (und Tests) obwohl –

+0

obj.GetType() bezieht sich auf MyObject [j]/MyObject [i], war nur ein bisschen schneller zu schreiben. Ich werde jetzt bearbeiten. –

0

Eine bessere Lösung für primitive Typen, die ist wie das nicht eine switch-Anweisung erforderlich: (VB.Net)

Lösungen für Multiplizieren, Dividieren usw. sind ähnlich. Ich hoffe, dass die Konvertierung in C# nicht zu schmerzhaft ist! Es ist wichtig, dass AddT freigegeben (statisch) ist, da das erneute Kompilieren des Lambda-Ausdrucks jedes Mal Taktzyklen verschwendet. Schade. Net hat keine "MyType implementiert {+, -, *, etc}"!

Verwandte Themen