1

Possible Duplicate:
Generic type from string value

Given a scenario, Class Car: Transport, Class Bus: Transport, Interface Transport,
Get(): Generics Method

Is it possible to do something like this?

Transport t= Get<"Car">(string color);

public T Get<T>(string color)
{
  return new T(color);
}

P/S: There's a reason to assign it as string, dynamically, regardless of return type.

Community
  • 1
  • 1
Roy Lee
  • 10,572
  • 13
  • 60
  • 84
  • Not the way you are suggesting. In your case "Car", "Bus", "Bike" will always be a type of string. You could switch on the string, create and return the appropriate object. – Steve Wellens Dec 29 '12 at 17:38
  • you dont wanna do that, review your design. – DarthVader Dec 29 '12 at 17:39
  • seen, not answering my question :) – Roy Lee Dec 29 '12 at 17:47
  • `(Transport)Activator.CreateInstance(Type.GetType("...."))` – L.B Dec 29 '12 at 17:52
  • 1
    @Roylee I know this doesn't answer your question, so I just moved it to be a comment, but I just wanted to point out that in order for that code to even compile, you would need a `where T : new()` constraint on the generic type parameter `T` in the `Get(string)` method. – jam40jeff Dec 29 '12 at 19:04

4 Answers4

2

If you want having Get works with a string you have two options: Add a non generic Get taking a Type as a paremter, something like:

public object Get(Type t);

so you can pass a type created form a string. A second option could be reflection:

MethodInfo method = typeof(YourType).GetMethod("Get");
MethodInfo generic = method.MakeGenericMethod(myType);

then you can invoke generic as if it was closed on to the type myType.

If I can suggest which one to use, and if you can refactor the Get method, I would suggest adding a non generic version of that method. The reflection version works if you really can't modify the library code. The drawback in using reflection is performance as you probably guess: you can decide if you can stay with it or not.

EDIT

Of course, my discussion does not apply if your method is really just creating the final object:

In this case activator works as a charm by passing the complete type name:

Activator.CreateInstance(Type.GetType("yourtypename"));

You generally can create the type based on just the simple name ( Car,Bus, etc ) because you need to fully qualify with a namespace and an assebly if the type is not the ExecutingAssembly. In this case you have to use some convention/configuration to simplify the code readability.

ADDITION

If you need to pass parameters too, I think you can try to start using a simple IoC ( I would not recomend one in particular, choose one widely used you like ) that can solve all these issues for you.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
1

If you don't know the class' name at compile type, you won't be able to use generics. You could use Activator.CreateInstance though:

object obj = Activator.CreateInstance(Type.GetType(assemblyQualifiedTypeName));

This assumes that the type you're creating has a default constructor.

Adi Lester
  • 24,731
  • 12
  • 95
  • 110
0

Use reflection to get a reference to the type from the type name, then use Activator.CreateInstance to, well, create an instance.

phoog
  • 42,068
  • 6
  • 79
  • 117
0

No, not with generics because a generic argument needs to be resolved at compile time.

However you could certainly pass your type as a string in a parameter and have your method return 'dynamic'.

var aCar = Get("Car") as Car;

public dynamic Get(string type)
{
  return Activator.CreateInstance(Type.GetType(type));
}
Jim G.
  • 15,141
  • 22
  • 103
  • 166