2009-09-03 21 views
11

Ten film okazał się dla mnie trochę skomplikowany. Zastanawiam się, czy możliwe jest wpisanie rzutowania obiektu przy użyciu obiektu System.Type.Typ Rzucanie obiektu przy użyciu obiektu "Typ" w języku C#

ja pokazano poniżej, co mam na myśli:

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

Powyższe jest rodzajowy interfejs, dlatego używam „obiekt” dla typów.

Odpowiedz

8

Typowym sposobem na to jest stosowanie leków generycznych, jak tak:

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

Jak wspomniano w komentarzu poniżej, leki generyczne są bardzo podobne do C++ Szablony. Możesz znaleźć MSDN documentation for Generics here, a artykuł "Differences Between C++ Templates and C# Generics (C# Programming Guide)" będzie prawdopodobnie pomocny.

W końcu mogę nie rozumieć, co chcesz zrobić w treści metody: nie jestem pewien, w jaki sposób przekształcić dowolny typ T w inny dowolny typ T2, chyba że podasz ograniczenia dla typów ogólnych. Na przykład konieczne może być określenie, że oba muszą implementować pewien interfejs. Constraints on Type Parameters (C# Programming Guide) opisuje, jak to zrobić w języku C#.

Edit: Biorąc pod uwagę zmienione pytanie, myślę this answer from Marco M. jest prawidłowe (. To jest, myślę, że należy użyć Converter delegata gdzie aktualnie próbuje użyć interfejsu IDataAdapter)

+1

I nie udało się go wyczyścić w przykładzie, ale dwie metody znajdują się w interfejsie IDataAdapter. – Ryall

+0

Jeszcze raz dziękuję, Jeff. – Ryall

+0

Nie ma problemu, a ja ponownie zaktualizowałem swoją odpowiedź. –

2

powyżej jest rodzajowy interfejs, dlatego używam „obiekt” dla typów

Czy nie byłoby bardziej sensowne użycie rzeczywisty interfejs generic:

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

    return output; 
} 

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

Te wyglądają jak szablony z C++ - w rzeczywistości nie zakryły ich jeszcze w języku C#. Dzięki! – Ryall

+0

Jestem trochę zdezorientowany, w jaki sposób używasz "U" poza ogólną. Jaki zakres jesteś podany? – Ryall

+0

@Kelix: "U" byłby twoim prawdziwym typem, tak naprawdę nie używałbyś "U" w ten sposób.Spójrz na odpowiedź @ Jeffa i zauważ, że jego T2 jest zastąpione przez "ciąg" i dopasowuje się w ten sam sposób. –

3

Jesteś lepiej wyłączyć za pomocą coś jak delegata Converter

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

na przykład, sprawdź 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

Jak to umożliwia obiektowi typu rzutowanie innego obiektu? Tinput i TOutput nie są obiektami i muszą być znane podczas kompilacji. – Despertar

7

Dlaczego się to skomplikowane, gdy masz pewność, że zwraca ciąg ?

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

Gdybym nie zrozumiałeś tego, co mówisz, jest tu jeszcze jeden sposób

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

Ponieważ przykładem jest interfejs - aktualizacja teraz. – Ryall

+0

Zaktualizowany, dziękuję za odpowiedź. – Ryall

+0

Zdobędę 1 za to! Podoba mi się idea '' Convert.ChangeType() '' i podanie typu obiektu jako 2. argumentu, więc zostanie zmieniony na ten typ. Pracuję nad inną biblioteką i mam nadzieję, że to uratuje moją noc. Dzięki @shahkalpesh –

2

To właśnie poszły z (w oparciu off struktury 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(); 
    } 
} 
Powiązane problemy