C# 避免在switch语句中硬编码

C# 避免在switch语句中硬编码,c#,if-statement,switch-statement,hard-coding,C#,If Statement,Switch Statement,Hard Coding,我有一个具有两个属性的对象:Text和Type 为了避免硬编码类型,我将它们放在数据库中,以便将来可以将它们添加到数据库中。目前的类型是URL、用户名和ID 但是,我现在想运行一个实用程序方法来清理对象的文本字段,该字段是对象所基于的类型(例如,如果是URL,则添加“http://”) 有没有一种方法可以在Utilities类中执行此操作,而无需在switch语句/if else块中硬编码类型 switch (type) { case 1: TidyUrl();

我有一个具有两个属性的对象:
Text
Type

为了避免硬编码类型,我将它们放在数据库中,以便将来可以将它们添加到数据库中。目前的类型是
URL、用户名和ID

但是,我现在想运行一个实用程序方法来清理对象的
文本
字段,该字段是对象所基于的
类型
(例如,如果是URL,则添加“http://”)

有没有一种方法可以在Utilities类中执行此操作,而无需在switch语句/if else块中硬编码类型

switch (type)
{
    case 1:
        TidyUrl();
    case 2:
        TidyUsername();
    case 3:
        TidyID();
    default:
        break;
}
在本例中,我将从数据库('Type'表)中硬编码ID,这绝不是一件好事


有更好的方法吗?

您可以使用枚举帮助提高可读性

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

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

此枚举需要与数据库保持协调。

您可以使用枚举帮助提高可读性

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

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

此枚举需要与数据库保持协调。

一种方法是使用多态性。您的每个“类型”都有单独的类,它们将使用类似于
Tidy
的方法实现一个公共接口(或有一个公共基类),每个方法都有自己的逻辑。

一种方法是使用多态性。您的每个“类型”都有单独的类,它们将使用类似于
Tidy
的方法实现一个公共接口(或有一个公共基类),其中每个类都有自己的逻辑。

传统上,这是使用公共接口来处理的,并动态构建一个具体的实现来完成实际工作

例如:

public interface ITidy
{
   string Tidy(string input);
}
然后是实现

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

等等,其他类型的整理。现在,您需要一种方法来从您正在查看的类型实例化正确的具体类(
UrlTidy
IdTidy
等)。一种方法是将类名与类型放在数据库中,并使用反射来实例化
ITidy
的正确实现。另一个wat是有一个
工厂
类,它使用一些其他方法根据类型实例化正确的
ITidy

传统上,这是使用公共接口处理的,并动态构建具体实现来完成实际工作

例如:

public interface ITidy
{
   string Tidy(string input);
}
然后是实现

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

其他类型的整理工作也是如此。现在,您需要一种方法来从您正在查看的类型实例化正确的具体类(
UrlTidy
IdTidy
等)。一种方法是将类名与类型放在数据库中,并使用反射来实例化
ITidy
的正确实现。另一个wat是有一个
工厂
类,它使用一些其他方法根据类型实例化正确的
ITidy

您可以使用
枚举类型
,但它们的常量值必须在编译时确定。您可以在
enum
中进行类不变性检查,以确保与数据库一致


但是在数据库中使用它们如何使其可扩展呢

您可以使用
枚举类型
,但它们的常量值必须在编译时确定。您可以在
enum
中进行类不变性检查,以确保与数据库一致


但是在数据库中使用它们如何使其可扩展呢

正如奥德所说,使用枚举:

public enum Types
{
    Type1 = 1,
    Type2 = 2,
    Type3 = 3
}
然后,可以将类型变量强制转换为枚举,使整数映射到数据库ID:

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

希望这有帮助

正如奥德所说,使用枚举:

public enum Types
{
    Type1 = 1,
    Type2 = 2,
    Type3 = 3
}
然后,可以将类型变量强制转换为枚举,使整数映射到数据库ID:

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

希望这能有所帮助

是的,我以前也这样做过,但这似乎只是把相同的问题(保持ID同步)放在了不同的地方。@finoutlook-但至少很清楚那个地方在哪里。根据我的经验,你必须在代码库中的某个地方有一个映射。是的,我同意它更清晰(并且可以将其他映射组合在一起,例如在一个枚举器类中),并且比在代码中传播要好。是的,我过去做过这件事,但它似乎只是解决了同样的问题(保持ID同步)在一个不同的地方。@finoutlook-但至少很清楚那个地方在哪里。根据我的经验,你必须在代码库中的某个地方有一个映射。是的,我同意它更清晰(并且可以将其他映射组合在一起,例如在一个枚举器类中),而且比通过代码传播要好。还有一个工厂方法,它将查找数据库中编码的类型,并创建该类型的新对象。可能使用
开关
语句;)@Oded——确切地说,无论选择什么,我都必须将代码直接链接到数据库中的内容是的,这是真的;但是这种技术避免了那些switch语句的扩散。你只需要一个。或者无,如果您更喜欢使用反射…和工厂方法,该方法将查找数据库中编码的类型并创建该类型的新对象。可能使用
开关
语句;)@Oded——确切地说,无论选择什么,我都必须将代码直接链接到数据库中的内容是的,这是真的;但是这种技术避免了那些switch语句的扩散。你只需要一个。或者没有,如果您更喜欢使用反射…将类或方法名称放入数据库就像硬编码一样。不过,这可能更可取。@finoutlook-no它与硬编码完全不同。完全相反,允许您动态扩展类型(假设您发布了包含该类的新程序集)。它类似于一个插件系统,允许您扩展应用程序的功能,而无需发布软件的完整性。是的,我看到了它在数据库中的优势。使维护更加容易,而且您是对的,它可以动态更改。将类或方法名称放入数据库就像硬编码另一个