开发者

Is a switch statement ok for 30 or so conditions?

开发者 https://www.devze.com 2022-12-27 02:34 出处:网络
I am in the final stages of creating an MP4 tag parser in .Net. For those who have experience with tagging music you would be aware that there are an average of 30 or so tags. If tested out different

I am in the final stages of creating an MP4 tag parser in .Net. For those who have experience with tagging music you would be aware that there are an average of 30 or so tags. If tested out different types of loops and it seems that a switch statement with Const values seems to be the way to go with regard to catching the tags in binary.

The switch allows me to search the binary without the need to know which order the tags are stored or if there are some not present but I wonder if anyone would be against using开发者_开发知识库 a switch statement for so many conditionals.

Any insight is much appreciated.

EDIT: One think I should add now that where discussing this is that the function is recursive, should I pull out this conditional and pass the data of to a method I can kill?


It'll probably work fine with the switch, but I think your function will become very long.

One way you could solve this is to create a handler class for each tag type and then register each handler with the corresponding tag in a dictionary. When you need to parse a tag, you can look up in the dictionary which handler should be used.


Personally, if you must, I would go this way. A switch statement is much easier to read than If/Else statements (and at your size will be optimized for you).

Here is a related question. Note that the accepted answer is the incorrect one.

Is there any significant difference between using if/else and switch-case in C#?


Another option (Python inspired) is a dictionary that maps a tag to a lambda function, or an event, or something like that. It would require some re-architecture.


For something low level like this I don't see a problem. Just make sure you place each case in a separate method. You will thank yourself later.


To me, having so many conditions in a switch statement gives me reason for thought. It might be better to refactor the code and rely on virtual methods, association between tags and methods, or any other mechanism to avoid spagetti code.


If you have only one place that has that particular structure of switch and case statements, then it's a matter of style. If you have more than one place that has the same structure, you might want to rethink how you do it to minimize maintenance headaches.


It's hard to tell without seeing your code, but if you're just trying to catch each tag, you could define an array of acceptable tags, then loop through the file, checking to see if each tag is in the array.


ID3Sharp on Sourceforge has a http://sourceforge.net/projects/id3sharp/ uses a more object oriented approach with a FrameRegistry that hands out derived classes for each frame type.

It's fast, it works well, and it's easy to maintain. The 'overhead' of creating a small class object in C# is negligible compared to opening an MP4 file to read the header.


One design that might be useful in some case (but from what I've seen would be over kill here):

class DoStuff
{
   public void Do(type it, Context context )
   {
      switch(it)
      {
          case case1: doCase1(context) break;
          case case2: doCase2(context) break;
          //...
      }
   }
   protected abstract void doCase1(Context context);
   protected abstract void doCase2(Context context);
   //...
}

class DoRealStuff : DoStuff
{
   override void doCase1(Context context) { ... }
   override void doCase2(Context context) { ... }
   //...
}


I'm not familiar with the MP4 technology but I would explore the possiblity of using some interfaces here. Pass in an object, try to cast to the interface.

public void SomeMethod(object obj)
{
  ITag it = obj as ITag;

  if(it != null)
  {
    it.SomeProperty = "SomeValue";
    it.DoSomthingWithTag();
  }
}


I wanted to add my own answer just to bounce off people...

  1. Create an object that holds the "binary tag name", "Data", "Property Name".
  2. Create a list of these totaling the amount of tags known adding the tag name and property name.
  3. When parsing use linq to match the found name with the object.binarytagname and add the data
  4. reflect into the property and add the data...


What about good old for loop? I think you can design it that way. Isn't switch-case only transformed if-else anyway? I always try to write code using loop if amount of case statements is becoming higher than acceptable. And 30 cases in switch is too high for me.


You almost certainly have a Chain of Responsibility in your problem. Refactor.

0

精彩评论

暂无评论...
验证码 换一张
取 消