Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# method to return a type

I have couple of classes that are identified by some ID (which is unique integer for every class). Next I need a method which takes an integer (ID) as argument and return corresponding class type. So far I have come to this:

public static Type GetById(int id)
{
    switch (id)
    {
        case 1: return (new ClassA()).GetType();
        case 2: return (new ClassB()).GetType();
        case 3: return (new ClassC()).GetType();
        // ... and so on
    }
}

For now it seems that it works, but for some reason I don't like that I have to instantiate the class to get its type. Could this cause any problems?

Another solution I found is to use Type.GetType(classNameAsString) method, but I guess this could cause some runtime errors or bugs in case class name is changed (i.e. I change the name of class, but forgot to update the GetById method).

Is there some better way to do this?

like image 960
Jaroslav Loebl Avatar asked Aug 26 '15 15:08

Jaroslav Loebl


3 Answers

Use the typeof operator instead

public static Type GetById(int id)
{
    switch (id)
    {
        case 1: return typeof(ClassA);
        case 2: return typeof(ClassB);
        case 3: return typeof(ClassC);
        // ... and so on
    }
}

As a side note, I would seriously question this whole design - it feels weird to map types to integers.

like image 178
dcastro Avatar answered Sep 27 '22 18:09

dcastro


Why don't you just declare a dictionary?

  private static Dictionary<int, Type> types = new Dictionary<int, Type>() {
    {1, typeof(ClassA)},
    {2, typeof(ClassB)},
    {3, typeof(ClassC)},
    ... and so on
  };

  public static Type GetById(int id) {
    Type result = null;

    if (types.TryGetValue(id, out result))
      return result;

    return null; // or throw exception
  }
like image 27
Dmitry Bychenko Avatar answered Sep 27 '22 17:09

Dmitry Bychenko


Another alternative would be creating an enum:

public enum ClassType
{
    ClassA = 1,
    ClassB = 2,
    ClassC = 3
}

And then changing your method to accept this enum and return the type:

public static Type GetById(ClassType id)
{
    //Will return null if the Type is not found, 
    //Add true as a second parameter to throw if not found
    return Type.GetType(id.ToString());
}

Doing so will remove magic numbers from your code, but will only work as long as your classes names match the enum options. This will make your code significantly smaller, but as pointed by others, you should really question your application design because this doesn't feel quite right.

like image 33
William Barbosa Avatar answered Sep 27 '22 18:09

William Barbosa