views:

339

answers:

4

I'm wondering if it's possible to cast an object to a Type... I've just started using Reflection, so maybe I'm doing it all wrong but here's what I would like to do:

...
Type type = ...;
Type interfaceType = someOtherType.GetInterface("IConverter`2");

return (Cast to interfaceType)Activator.CreateInstance(type);

Is the cast to the interface possible?

Update:

Compiler says that T and K can not be found. The myInterface Type instance knows the T and K class...

public IConverter<T, K> GetConverter(Type type)
{
    if (dtoModelDictionary.ContainsKey(type))
    {
     Type foundType = dtoModelDictionary[type];
     Type myInterface = foundType.GetInterface("IConverter`2");

     return (IConverter<T, K>)Activator.CreateInstance(foundType); 
    }
    else if (dalModelDictionary.ContainsKey(type))
    {
     Type foundType = dalModelDictionary[type];

     return (IConverter<T, K>)Activator.CreateInstance(foundType);
    }
    else
    {
     throw new System.Exception();
    }
}

Second update:

public SomeClass GetConverter(Type type)
    {
        if (dtoModelDictionary.ContainsKey(type))
        {
         Type foundType = dtoModelDictionary[type];
         Type myInterface = foundType.GetInterface("IConverter`2");

         IConverter<T, K> converter = (IConverter<T, K>)Activator.CreateInstance(foundType); 
            return converter.someMethod(); 
        }
    }
+1  A: 

Not really, no... at least not in this way. The problem is that your return value is going to have to be whatever your method's return value is typed as. Because everything must be typed at compile-time, there is limited or no real use case that I can see for this particular kind of type coersion - maybe you can say some more about what you are trying to accomplish?

Now if you are using generics, you do have a run-time typing story, you can return your Type parameter type:

public T MyMethod<T>(...)
...
return (T)Activator.CreateInstance(type);
ZeroBugBounce
Thx, I updated the question with some code. Your return (T) is what my compiler doesn't like because it says that the type or namespace T cannot be found.
Lieven Cardoen
+1  A: 

You can only cast an object to something that it actually is. You can for example cast a String reference to IEnumerable, but you can't cast it to char[].

If what your method returns actually implements the interface, you can just cast it as usual.

Example:

return (IConverter<int,string>)Activator.CreateInstance(type);

Edit:
You need to make the method generic so that you can specify the data types when you call it:

public IConverter<T, K> GetConverter<T, K>(Type type) {
   ...
}
Guffa
That's just the problem. I don't know at compile time what T and K will be...
Lieven Cardoen
If you don't know the type at compile time then you can't declare a variable with that type to store the reference in, so it's pointless to do a cast.
Guffa
+2  A: 

Answer to you update:

You cannot cast to a type where the generic arguments are not defined. T and K must be defined for the method that is using it.

Either declare it:

public IConverter<T, K> GetConverter<T, K>(Type type)

Or, if you face the problem often that this interface is used but you don't know any T or K types, use an interface without generics:

interface IConverter
{ 
  // general members
}

interface  IConverter<T, K> : IConverter 
{
  // typesave members
}

public IConverter GetConverter(Type type)
{
  // ...
  return (IConverter)Activator.CreateInstance(type);
}
Stefan Steinegger
Ok, I'll try this, but what if I want to trigger a method out of the second interface (typesave members)? (see new update). thx.
Lieven Cardoen
You cannot call typesave members without knowing the types. If you know them, you can cast it to the appropriate IConverter<T, K>. But it's better to provide everything in the general IConverter interface which needs to be available without knowing the types. I have sometimes properties like `object UntypedValue { get; }` to provide access to values without knowing the type. So the rule is: use T and K whenever you know them, but provide a way to do everything without knowing them.
Stefan Steinegger
A: 

You can do this:

var type = typeof(IConverter<,>).MakeGenericType(new Type[] { typeof(T), typeof(K) });
eulerfx