2009-09-03 3 views
11

Dieser hat sich für mich bisher als etwas knifflig erwiesen. Ich frage mich, ob es möglich ist, ein Objekt mit einem System.Type-Objekt zu umwandeln.Typ Casting eines Objekts mit einem "Type" -Objekt in C#

Ich habe unten gezeigt, was ich meine: für die Typen

public interface IDataAdapter 
{ 
    object Transform(object input); 
    Type GetOutputType(); 
} 

public class SomeRandomAdapter : IDataAdapter 
{ 
    public object Transform(object input) 
    { 
     string output; 

     // Do some stuff to transform input to output... 

     return output; 
    } 

    public Type GetOutputType() 
    { 
     return typeof(string); 
    } 
} 

// Later when using the above methods I would like to be able to go... 
var output = t.Transform(input) as t.GetOutputType(); 

Die oben ist eine generische Schnittstelle, weshalb ich „Objekt“ verwenden.

Antwort

8

Der typische Weg, dies zu tun ist, Generika zu verwenden, etwa so:

public T2 Transform<T, T2>(T input) 
{ 
    T2 output; 

    // Do some stuff to transform input to output... 

    return output; 
} 

int number = 0; 
string numberString = t.Transform<int, string>(number); 

Wie Sie unten in Ihrem Kommentar erwähnt, sind Generika C++ Templates sehr ähnlich. Sie können die MSDN documentation for Generics here finden, und der Artikel "Differences Between C++ Templates and C# Generics (C# Programming Guide)" wird wahrscheinlich hilfreich sein.

Schließlich könnte ich Missverständnis, was Sie in der Methode body tun wollen: Ich bin mir nicht sicher, wie Sie einen beliebigen Typ T in einen anderen beliebigen Typ T2 transformieren, sofern Sie Einschränkungen für die generischen Typen angeben. Beispielsweise müssen Sie möglicherweise angeben, dass beide eine Schnittstelle implementieren müssen. Constraints on Type Parameters (C# Programming Guide) beschreibt, wie man das in C# macht.

bearbeiten: Ihre überarbeitete Frage gegeben, ich glaube this answer from Marco M. korrekt ist (. Das heißt, ich glaube, Sie die Converter Delegierten verwenden sollten, wo Sie gerade versuchen, Ihre IDataAdapter Schnittstelle verwenden)

+1

I hat es nicht gemacht, um in dem Beispiel zu klären, aber die zwei Methoden sind innerhalb einer Schnittstelle IDataAdapter. – Ryall

+0

Danke nochmal Jeff. – Ryall

+0

Kein Problem, und ich habe meine Antwort ein wenig aktualisiert. –

2

Die oben ist eine generische Schnittstelle, weshalb ich „Objekt“ verwenden für die Typen

Wäre es nicht sinnvoll, eine tatsächliche generische Schnittstelle zu verwenden:

public U Transform<T, U>(T input) 
{ 
    string output; 

    return output; 
} 

U output = t.Transform(input) as U; 
+0

Diese sehen wie Vorlagen aus C++ aus - haben sie in C# noch nicht behandelt. Vielen Dank! – Ryall

+0

Ich bin ein wenig verwirrt, wie Sie 'U' außerhalb des Generikums verwenden. Welchen Umfang haben Sie? – Ryall

+0

@Kelix: "U" wäre dein eigentlicher Typ, du würdest "U" nicht wirklich so benutzen.Schauen Sie sich @ Jeffs Antwort an und beachten Sie, dass sein T2 durch "String" ersetzt wird und auf die gleiche Weise übereinstimmt. –

3

Sie sind besser dran, so etwas wie die Konverter Delegat

public delegate TOutput Converter<TInput, TOutput>(TInput input); 

Beispiel für die Verwendung Besuche msdn

public static void Main() 
{ 
    // Create an array of PointF objects. 
    PointF[] apf = { 
     new PointF(27.8F, 32.62F), 
     new PointF(99.3F, 147.273F), 
     new PointF(7.5F, 1412.2F) }; 

    // Display each element in the PointF array. 
    Console.WriteLine(); 
    foreach(PointF p in apf) 
     Console.WriteLine(p); 

    // Convert each PointF element to a Point object. 
    Point[] ap = Array.ConvertAll(apf, 
     new Converter<PointF, Point>(PointFToPoint)); 

    // Display each element in the Point array. 
    Console.WriteLine(); 
    foreach(Point p in ap) 
    { 
     Console.WriteLine(p); 
    } 
} 

public static Point PointFToPoint(PointF pf) 
{ 
    return new Point(((int) pf.X), ((int) pf.Y)); 
} 
+0

Wie erlaubt dies einem Type-Objekt, ein anderes Objekt zu werfen? TInput und TOutput sind keine Objekte und müssen zum Zeitpunkt der Kompilierung bekannt sein. – Despertar

7

Warum es kompliziert machen, wenn Sie sicher sind, dass sie einen String zurückgibt ?

var output = t.Transform(input) as string; 

Wenn ich das falsch verstanden haben, was Sie sagen, hier ist eine weitere Möglichkeit,

var output = Convert.ChangeType(t.Transform(input), t.GetOutputType()); 
+1

Weil das Beispiel eine Schnittstelle ist - jetzt aktualisieren. – Ryall

+0

Aktualisiert, danke für die Antwort. – Ryall

+0

Ich werde 1 dafür schlagen! Ich mag die Idee von '' Convert.ChangeType() '' und die Angabe des Typs des Objekts als 2. Argument, so dass es zu diesem Typ geändert wird. Ich arbeite an einer anderen Bibliothek und hoffe, dass dies meine Nacht retten wird. Danke @Shahkalpesh –

2

Das ist, was ich mit (bezogen von der IEnumerable Struktur) gegangen:

public interface IDataAdapter 
{ 
    object Transform(object input); 
} 

public interface IDataAdapter<OutT, InT> : IDataAdapter 
{ 
    OutT Transform(InT input); 
} 

public class SomeClass : IDataAdapter<string, string> 
{ 
    public string Transform(string input) 
    { 
     // Do something... 
    } 

    public object Transform(object input) 
    { 
     throw new NotImplementedException(); 
    } 
}