开发者

Avoid hardcoding in switch statement

开发者 https://www.devze.com 2023-04-08 06:44 出处:网络
I have an object with has two properties: Text and Type. To avoid hard-coding the Types, I put them in the database, so they can be added to in future. At the moment the types are URL, Username and I

I have an object with has two properties: Text and Type.

To avoid hard-coding the Types, I put them in the database, so they can be added to in future. At the moment the types are URL, Username and ID.

However, I now want to run a Utility method to clean up the object's Text field based on which Type the object is (e.g. add 'http://' if its a URL).

Is there a way to do this in the Utilities class without hard-coding the types in a switch statement/if else block.

switch (type)
{
    case 1:
        TidyUrl();
    case 2:
        TidyUsername();
    case 3:
        TidyID();
    default:
        break;
}

In this exampl开发者_开发知识库e I'm hardcoding the IDs from the database ('Type' table), which can never be a good thing!

Is there a better way to do this?


You can use an enum to help with readability.

enum MyTypes
{
 URL = 1,
 UserName = 2,
 Id = 3,
}

switch (myType)
{
    case MyTypes.URL:
        TidyUrl();
    case MyTypes.UserName:
        TidyUsername();
    case MyTypes.Id:
        TidyID();
    default:
        break;
}

This enum will need to be kept coordinated with the database.


One way is to use polymorphism. You'd have separate classes for each of your "types" and they'd implement a common interface (or have a common base class) with a method like Tidy, where each would do its own logic.


Traditionally this is handled using a common interface, and dynamically constructing a concrete implementation to do the actual work.

for example:

public interface ITidy
{
   string Tidy(string input);
}

then the implementations

public class UrlTidy : ITidy
{
    public string Tidy(string input)
    {
        // do whatever you need to the url
    }
}

And so on for the other types of tidying. Now you need a way of instantiating the right concrete class (UrlTidy, IdTidy etc) from the type you are looking at. One way to do this might be to put the class name in the database along side the type, and use reflection to instantiate the right implementation of ITidy. Another wat would be to have a Factory class which uses some other method to instantiate the right ITidy based on type.


You could use enum Type but their constant values will have to determined at compile time. You can put a class invariance check in the enum to ensure that the are consistent with the database.

But how does having them in the database make it extendible?


As Oded said, use an enum:

public enum Types
{
    Type1 = 1,
    Type2 = 2,
    Type3 = 3
}

You can then cast your type variable to the enum, having the integers map to the database IDs:

switch ((Types)type)
{
    case Types.Type1:
        break;
    case Types.Type2:
        break;
    ...
}

Hope that helps

0

精彩评论

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