1

I have a method in C# which receives a generic type as argument:

private void DoSomething<T>(T param)
{
    //...
}

I need to perform different things depending on what type is param of. I know I can achieve it with several if sentences, like this:

private void DoSomething<T>(T param)
{
    if (param is TypeA)
    {
        // do something specific to TypeA case

    } else if (param is TypeB)
    {
        // do something specific to TypeB case

    } else if ( ... )
    {
        ...
    }

    // ... more code to run no matter the type of param
}

Is there a better way of doing this? Maybe with switch-case or another approach that I'm not aware of?

zed
  • 2,298
  • 4
  • 27
  • 44
  • 8
    In general, if you're doing something inherently type-specific, a generic method is the wrong tool. Perhaps create an method with type-specific overloads, which calls the generic method upon completion? – Glorin Oakenfoot Jan 25 '16 at 22:29
  • Can you explain what you are trying to do? – Yacoub Massad Jan 25 '16 at 22:38
  • 3
    this might make for some good reading [Constraints on Type Params](https://msdn.microsoft.com/en-us/library/d5x73970.aspx) – MethodMan Jan 25 '16 at 22:39
  • @GlorinOakenfoot, I also thought on overloads; I was looking for different ideas and alternatives. You are right, is the way to go. Nevertheless, I got interesting feedback from every answer, thank you all (+1). – zed Jan 26 '16 at 14:49

4 Answers4

6

Just use overloading instead of generics.

John
  • 57
  • 1
4

If project/logic structure allows it would be nice to move DoSomething into T and describe it with IDoSomething interface. This way you can write:

private void DoSomething<T>(T param) where T:IDoSomething
{
    param.DoSomething()
}

If that's not an option then you can setup dictionary of rules

var actionsByType = new Dictionary<Type, Action<T /*if you neeed that param*/>(){
   { Type1, DoSomething1 },
   { Type2, DoSomething2 },
   /..
}

and in your method you can call:

private void DoSomething<T>(T param){
  //some checks if needed
  actionsByType[typeof(T)](param/*if param needed*/);
}
serhiyb
  • 4,753
  • 2
  • 15
  • 24
  • I was about to go with your first idea, pretty nice! But my project structure didn't allow it. The second is also good, but I'll try with simple overloads first. Thanks! – zed Jan 26 '16 at 14:55
3

You can create a specific method for a particular type.

    private void DoSomething<T>(T param)
    {
        //...
    }

    private void DoSomething(int param) { /* ... */ }

    private void DoSomething(string  param) { /* ... */ }
Valentin
  • 5,380
  • 2
  • 24
  • 38
1

As mentioned before if its a simple case use overloading. Anything stranger you can adapt this (its quick and dirty apologies).

class Program
{

    interface IDoSomething<T>
    {
        void DoSomething(T param);
    }

    class Test : IDoSomething<int>, IDoSomething<string>
    {
        public void DoSomething(int param)
        {

        }

        public void DoSomething(string param)
        {

        }
    }

    static void Main(string[] args)
    {

        DoSomething(4);

    }

    static void DoSomething<T>(T param)
    {
        var test = new Test();
        var cast = test as IDoSomething<T>;
        if (cast == null) throw new Exception("Unhandled type");
        cast.DoSomething(param);
    }
}
Barry
  • 1,084
  • 1
  • 8
  • 22