3

我正在查看并试图了解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
}

这是 Udp 服务:

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
    }
}

这是我的输出:

截屏

但是我不禁认为开发人员出于我没有看到的原因而使用了所有这些复杂性。

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

4

3 回答 3

6

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

不过,在这里使用 a 没有意义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);
    }
}
于 2012-12-30T22:59:47.303 回答
3

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

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

等等。虽然未知的会像你展示的那样:

1 (1)
2 (2)

等等

于 2012-12-30T23:00:12.027 回答
2

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

如果你想重构其中的一些代码,你可以将通用的“(端口)”部分移到开关之外,完全删除默认情况,并去掉不需要的临时变量。IE:

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();
}
于 2012-12-30T22:59:51.623 回答