如何重构方法

时间:2019-04-23 06:00:47

标签: c# .net refactoring

我有两种方法。它们非常相似。 我尝试使用泛型,但不适用于TryParse()

    public static int EnterIntengerNumber()
    {
        while (true)
        {
            Console.Write("Enter an intenger number: ");
            if (int.TryParse(Console.ReadLine(), out int number))
            {
                return number;
            }
            else
            {
                ConsoleError("Incorrect value");
            }
        }
    }


    public static double EnterRealNumber()
    {
        while (true)
        {                
            Console.Write("Enter a number: ");
            if (double.TryParse(Console.ReadLine(), out double number))
            {
                return number;                    
            }
            else
            {
                ConsoleError("Incorrect value");
            }
        }
    }

如何合并或重构它们?

3 个答案:

答案 0 :(得分:5)

您可以制作函数,该函数接受带有TryParse参数的委托并返回通用值。另外,您可以/必须输入字符串以询问正确的类型。但这可以通过以下示例进行改进:

    static void Main(string[] args)
    {
        var myDouble = EnterSomething<double>("a double", double.TryParse);
        var myInt = EnterSomething<int>("an interger", int.TryParse);
        Console.WriteLine(myDouble);
        Console.WriteLine(myInt);

        Console.ReadLine();
    }


    public delegate bool TryParseFunction<Tout>(string input, out Tout output);

    public static Tout EnterSomething<Tout>(string typeName, TryParseFunction<Tout> parser)
    {
        while (true)
        {
            Console.Write("Enter " + typeName + " number: ");
            if (parser(Console.ReadLine(), out Tout number))
            {
                return number;
            }
            else
            {
                Console.WriteLine("Incorrect value");
            }
        }
    }

小的附加说明:int.TryParse-传递给EnterSomething的方法不是调用TryParse。实际上,它只是“传递”函数,以便可以在EnterSomething中调用它。

不使用Func<>的原因是它不支持变量,请参见以下示例:Func<T> with out parameter

编辑:我删除了Tin类型的参数,因为无论如何输入都是字符串。

答案 1 :(得分:0)

您可以使用Convert.ChangeType

请记住,您最终将使用拳击,因此失去了使用泛型的意义。虽然您最终的代码更少。

    public static T EnterNumber<T> ()
    {
        while (true)
        {
            Console.Write("Enter an " + typeof(T) + " number: ");
            try
            {
                return (T) Convert.ChangeType(Console.ReadLine(), typeof(T));
            }
            catch (FormatException ex)
            {
                Console.Write("Incorrect format" + ex.Message);
            }
        }
    }

答案 2 :(得分:0)

您可以这样尝试:

public static int EnterIntengerNumber()
{
    return EnterNumber(t => int.TryParse(t, out int v) ? (int?)v : null)
}

public static double EnterRealNumber()
{
    return EnterNumber(t => double.TryParse(t, out double v) ? (double?)v : null)
}

private static T EnterNumber<T>(Func<string, T?> tryParse) where T : struct
{
    while (true)
    {
        Console.Write("Enter a number: ");
        T? result = tryParse(Console.ReadLine());
        if (result.HasValue)
        {
            return result.Value;
        }
        else
        {
            ConsoleError("Incorrect value");
        }
    }
}