2009-09-03 16 views
11

Questo ha dimostrato di essere un po 'complicato per me finora. Mi chiedo se è possibile digitare cast un oggetto usando un oggetto System.Type.Inserisci un oggetto utilizzando un oggetto "Tipo" in C#

ho illustrato qui di seguito quello che voglio dire:

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(); 

Quanto sopra è un'interfaccia generica ed è per questo che sto usando "oggetto" per i tipi.

risposta

8

Il modo tipico per farlo è quello di utilizzare farmaci generici, in questo modo:

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); 

Come lei ha ricordato nel vostro commento qui sotto, i generici sono molto simili a C++ Modelli. È possibile trovare il MSDN documentation for Generics here e l'articolo "Differences Between C++ Templates and C# Generics (C# Programming Guide)" sarà probabilmente utile.

Infine, potrei fraintendere ciò che si vuole fare all'interno del corpo del metodo: non sono sicuro di come trasformare un tipo arbitrario T in un altro tipo arbitrario T2, a meno che non si specificino vincoli sui tipi generici. Ad esempio, potrebbe essere necessario specificare che entrambi devono implementare un'interfaccia. Constraints on Type Parameters (C# Programming Guide) descrive come eseguire questa operazione in C#.

Edit: Data la tua domanda riveduta, penso this answer from Marco M. è corretta (. Che è, penso che si dovrebbe utilizzare il Converter delegato in cui si sta attualmente cercando di utilizzare l'interfaccia IDataAdapter)

+1

I non è riuscito a chiarire nell'esempio, ma i due metodi si trovano all'interno di un'interfaccia IDataAdapter. – Ryall

+0

Grazie ancora Jeff. – Ryall

+0

Nessun problema, e ho aggiornato di nuovo la mia risposta. –

2

Il di cui sopra è un'interfaccia generica ed è per questo che sto usando "oggetto" per i tipi

non sarebbe più sensato utilizzare un'interfaccia generica reale:

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

    return output; 
} 

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

Questi sembrano modelli da C++ - non li hanno ancora coperti in C# ancora. Grazie! – Ryall

+0

Sono un po 'confuso su come stai usando' U 'al di fuori del generico. Che scopo ti viene dato? – Ryall

+0

@Kelix: "U" sarebbe il tuo tipo attuale, non useresti realmente "U" in quel modo.Guarda la risposta di @ Jeff e nota che il suo T2 è sostituito da "stringa" e corrisponde allo stesso modo. –

3

Si sta meglio usando qualcosa come il convertitore delegato

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

per un esempio, controlla 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

In che modo questo consente a un oggetto Type di eseguire il cast di un altro oggetto? TInput e TOutput non sono oggetti e devono essere conosciuti al momento della compilazione. – Despertar

7

perché rendono complicato, quando si è certi che restituisce una stringa ?

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

Se ho capito male quello che stai dicendo, qui è un altro modo

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

Perché l'esempio è un'interfaccia - aggiornamento ora. – Ryall

+0

Aggiornato, grazie per la risposta. – Ryall

+0

Colpirò 1 per questo! Mi piace l'idea di '' Convert.ChangeType() '' e fornire il tipo dell'oggetto come secondo argomento, quindi verrà cambiato in quel tipo. Sto lavorando su un'altra libreria e spero che questo salverà la mia notte. Grazie a @shahkalpesh –

2

Questo è quello che ho passato con (in base al largo la struttura IEnumerable):

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(); 
    } 
}