views:

780

answers:

5

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.

+4  A: 

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

Jeff Sternal
I didn't make it to clear in the example but the two methods are within an interface IDataAdapter.
Nat Ryall
Thanks again Jeff.
Nat Ryall
No problem, and I've updated my answer a bit again.
Jeff Sternal
+2  A: 

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;

HTH, Kent

Kent Boogaart
These look like Templates from C++ - haven't actually covered them in C# yet. Thanks!
Nat Ryall
I am a little confused as to how you are using 'U' outside of the generic. What scope are you given?
Nat Ryall
@Kelix: "U" would be your actual type, you wouldn't really use "U" like that. Look at @Jeff's answer and notice his T2 is replaced by "string" and matches up in the same manner.
Ahmad Mageed
I could also use a 'var' and not cast at all if I am not mistaken?
Nat Ryall
+4  A: 

You are better off using something like the Converter delegate

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

for an example, check out msdn

Marco M.
+1  A: 

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());
shahkalpesh
Because the example is an interface - updating now.
Nat Ryall
Updated, thanks for the answer.
Nat Ryall
+2  A: 

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