将一个short作为枚举,然后转换为字符串有什么意义?

时间:2012-12-30 22:56:13

标签: c# refactoring

我正在查看并试图理解DnDns项目,这是一个非常令人印象深刻的项目,但我遇到了一种方法,我不明白其背后的原因。

public static string GetServByPort(short port, ProtocolType proto)
{
    StringBuilder ans = new StringBuilder();

    switch (proto)
    {
        case ProtocolType.Tcp: 
        {
            TcpServices tcps;
            tcps = (TcpServices)port;
            ans.Append(tcps);
            ans.Append("(");
            ans.Append(port);
            ans.Append(")");
            break;
        }
        case ProtocolType.Udp:
        {
            UdpServices udps;
            udps = (UdpServices)port;
            ans.Append(udps);
            ans.Append("(");
            ans.Append(port);
            ans.Append(")");
            break;
        }
        default:
        {
            ans.Append("(");
            ans.Append(port);
            ans.Append(")");
            break;
        }
    }
    return ans.ToString();
}

TcpServices和UdpServices是枚举。这是TcpServices:

public enum TcpServices : short
{
    /// <summary>
    /// Domain Name Server Port
    /// </summary>
    Domain = 53
}

这是UdpServices:

public enum UdpServices : short
{
    /// <summary>
    /// Domain Name Server Protocol Port
    /// </summary>
    Domain = 53
}

假设端口号为1.如果协议类型为TCP或UDP,则输出为:

  

1(1)

如果协议类型是其他任何内容,则输出为:

  

(1)

因此,我想为我的项目重写这个方法(仍然完全归功于原始开发人员等):

private static string GetServerByPort(short port, ProtocolType protocolType)
{
    if (protocolType == ProtocolType.Tcp || protocolType == ProtocolType.Udp)
    {
        return string.Format("{0}({0})", port);
    }

    return string.Format("({0})", port);
}

我编写了以下短控制台应用程序来测试:

using System;
using System.Net.Sockets;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(GetServByPort(1, ProtocolType.Tcp));
            Console.WriteLine(GetServByPort(2, ProtocolType.Udp));
            Console.WriteLine(GetServByPort(3, ProtocolType.SpxII));

            Console.ReadLine();
        }

        public static string GetServByPort(short port, ProtocolType proto)
        {
            switch (proto)
            {
                case ProtocolType.Tcp:
                    return string.Format("{0} ({1})", (TcpServices)port, port);
                case ProtocolType.Udp:
                    return string.Format("{0} ({1})", (UdpServices)port, port);
                default:
                    return string.Format("({0})", port);
            }
        }
    }

    public enum UdpServices : short
    {
        Domain = 53
    }

    public enum TcpServices : short
    {
        Domain = 53
    }
}

这是我的输出:

Screenshot

然而,我不禁想到开发人员因为我没有看到的原因而去了所有这些复杂性。

我的问题是我是否正确地按照我计划的方式重构这个方法,或者是否有充分的理由让原始开发人员做到这一点,我没有看到,这将导致我的问题如果我以更简单的方式做事?

3 个答案:

答案 0 :(得分:6)

在枚举上调用ToString()将使用枚举值 name (如果有)。 (当没有相应的命名值时,它将给出数字版本。)例如,在TcpServices情况下,如果值为53,则结果为Domain (53) 在原始代码中 - 但在您建议的替换代码中53 (53)

虽然在这里使用StringBuilder没有意义。我将原始方法重写为:

public static string GetServByPort(short port, ProtocolType proto)
{
    switch (proto)
    {
        case ProtocolType.Tcp: 
            return string.Format("{0} ({1})", (TcpServices) port, port);
        case ProtocolType.Udp:
            return string.Format("{0} ({1})", (UdpServices) port, port);
        default:
            return string.Format("({0})", port);
    }
}

答案 1 :(得分:3)

对于众所周知的服务,您的输出将如下所示:

Domain (53)
HTTP (80)
HTTPS (445)
FTP (21)

等。虽然未知的将像你所示:

1 (1)
2 (2)

答案 2 :(得分:2)

如果该值实际上是枚举成员之一,则该函数将返回类似“Domain(53)”而不是“53(53)”的内容。 StringBuilder基本上会调用ToString来获取所有内容以及枚举值,这些值将返回值的名称(如果存在)(否则为数字)。

如果要重构某些代码,可以将公共“(port)”部分移到交换机外部,完全删除默认情况,并删除不需要的临时变量。即:

public static string GetServByPort(short port, ProtocolType proto)
{
    StringBuilder ans = new StringBuilder();

    switch (proto)
    {
        case ProtocolType.Tcp: 
            ans.Append((TcpServices)port);
            break;
        case ProtocolType.Udp:
            ans.Append((UdpServices)port);
            break;
    }

    ans.Append("(").Append(port).Append(")");

    return ans.ToString();
}