This one has proven to be a little tricky for me so far. I am wondering if it is possible to type cast an object using a System.Type object.
I have illustrated below what I mean:
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();
The above is a generic interface which is why I am using "object" for the types.
The typical way to do that is to use generics, like 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);
As you mentioned in your comment below, generics are very similar to C++ Templates. You can find the MSDN documentation for Generics here, and the article "Differences Between C++ Templates and C# Generics (C# Programming Guide)" will probably be helpful.
Finally, I might be misunderstanding what you want to do inside the method body: I'm not sure how you'll transform an arbitrary type T
into another arbitrary type T2
, unless you specify constraints on the generic types. For example, you might need to specify that they both have to implement some interface. Constraints on Type Parameters (C# Programming Guide) describes how to do this in C#.
Edit: Given your revised question, I think this answer from Marco M. is correct (that is, I think you should use the Converter
delegate where you're currently trying to use your IDataAdapter
interface.)
Why make it complicated, when you are sure that it returns a string?
var output = t.Transform(input) as string;
If I have misunderstood what you are saying, here is one more way
var output = Convert.ChangeType(t.Transform(input), t.GetOutputType());
You are better off using something like the Converter delegate
public delegate TOutput Converter<TInput, TOutput>(TInput input);
for an example, check out 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));
}
This is what I have gone with (based off the IEnumerable structure):
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();
}
}
The above is a generic interface which is why I am using "object" for the types
Would it not make more sense to use an actual generic interface:
public U Transform<T, U>(T input)
{
string output;
return output;
}
U output = t.Transform(input) as U;