tags:

views:

75

answers:

4

I have a switch statement that executes some logic over and over. Rather then use cut and paste I wanted to put it into a function, but I am failing badly at this.

This is what I want to do, but it does not compile because the break tag in the function does not exist. Can anyone refactor this to a better working version?

switch(param.ToString())
{
  case "1":
  BreakIfNotArgumentType<B>(param);
 //do stuff
  break;
  case "2":
  BreakIfNotArgumentType<BF>(param);
 //do stuff
  break;
}

   private T BreakIfNotArgumentType<T>(object argumentObject)
    {
        if (argumentObject is T)
        {
            return (T)argumentObject;
        }
        else
        {
            break;
        }            
    }
A: 

You could have the function return a null if the argument can't be cast or throw an exception for a couple of ideas on how to handle that part of the code.

   private T BreakIfNotArgumentType<T>(object argumentObject)
    {
        if (argumentObject is T)
        {
            return (T)argumentObject;
        }
        else
        {
            return null;
        }            
    }

Or

   private T BreakIfNotArgumentType<T>(object argumentObject)
    {
        if (argumentObject is T)
        {
            return (T)argumentObject;
        }
        else
        {
            throw CustomException("Argument wasn't valid!");
        }            
    }
JB King
The exception solution is interesting, but there are performance concerns, and it is truly not an exceptional case; it's expected to happen at least once per switch statement. Therefore, I'd prefer the null solution.
Sean Reilly
That's fine, I just think the exception solution should be considered as if there is the requirement that something be of a particular type this should be enforced somehow. The null solution is more graceful though it does leave the code that calls this function to be aware that null can be returned.
JB King
@JB: The exception solution also leaves the code that calls the function to be aware that an exception can be thrown, which is arguably harder to know (or infer, anyway) than the possibility of a null.
Adam Robinson
A: 

Make your method to return a boolean and check the return value:

switch(param.ToString())
{
  case "1":
  if (CheckForArgumentType<B>(param))
  {
   // Do your cast here
   param = (B)param
  }
  else
     break;
  case "2":
  if (CheckForArgumentType<B>(param))
  {
   // Do your cast here
   param = (B)param
  }
  else
     break;
  }
  .................

   private bool CheckForArgumentType<T>(object argumentObject)
    {
        return (argumentObject is T)

    }
Michael D.
Is that function really more readable than just saying "if(param is B)" ?
Adam Robinson
Absolutely agree with you.I just did this to have "extendable" version in case you need more validation that just type check
Michael D.
A: 

if you only have 2 values to compare with - use IF statement instead

DmitryK
+2  A: 

Your function is essentially replicating the functionality of the as operator.

string foo = "foo";

....

object a = foo;
object b = 12;
....

string bar = a as string; // will give you "foo"
string zed = b as string; // returns null

The as operator functions as a runtime-safe cast. If the target instance can't be cast to the target type, then a null reference is assigned. Because of this, it will only work with reference types. The most common usage is like this...

string bar = a as string;

if(bar != null)
{
    // do stuff
}

Because this gives the type checking and casting operation in one statement.

You should post your switch statement and we may be able to streamline it better. Trying to write a truly inline function as you had (where you were expecting it to substitute the code in the function into your switch statement, which makes it more of a macro than a function) won't work.

Adam Robinson