操作可以概括吗?

时间:2011-01-21 21:05:12

标签: c#

我刚写了这段代码:

private double PerformOperation(OperationEnum operation, double aggregateValue, 
                                double sourceValue)
{
    if (operation == OperationEnum.Sum)
        return aggregateValue + sourceValue;
    if (operation == OperationEnum.Subtract)
        return aggregateValue - sourceValue;
    if (operation == OperationEnum.Multiply)
        return aggregateValue * sourceValue;
    if (operation == OperationEnum.Divide)
        return aggregateValue / sourceValue;
    throw new InvalidOperationException("Unsupported Aggregation Operation");
}

看起来非常重复。有没有办法概括这个?所以除了不同的标志外,我不需要有4条相同的线路?

(注意:如果有更好的方法不使用OperationEnum那么好)

8 个答案:

答案 0 :(得分:3)

您可以制作Dictionary<OperationEnum, Func<double, double, double>>

static readonly Dictionary<OperationEnum, Func<double, double, double>> operations = 
    new Dictionary<OperationEnum, Func<double, double, double>> {
        { OperationEnum.Sum, (a, b) => a + b },
        ...
    };

答案 1 :(得分:1)

它看起来对我来说是正确的,虽然我会使用switch声明。但也许我不明白你想做什么?

switch(operation)
{
    case OperationEnum.Sum:      return aggregateValue + sourceValue;
    case OperationEnum.Subtract: return aggregateValue - sourceValue;
    case OperationEnum.Multiply: return aggregateValue * sourceValue;
    case OperationEnum.Divide:   return aggregateValue / sourceValue;
    default:
        throw new InvalidOperationException("Unsupported Aggregation Operation");
}

它基本上是相同的,但至少它看起来更漂亮。

答案 2 :(得分:1)

您可以创建委托词典,因此您的功能将类似于:

private double PerformOperation(OperationEnum operation, double aggregateValue, 
                            double sourceValue)
{
    return operators[operation](aggregateValue, sourceValue);
}

答案 3 :(得分:1)

是的,使用List<Func<double, double, double>>

List<T>访问器的工作速度比Dictionary&lt;&gt;快得多访问器,与switch语句相当;)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace test
{
    class Program
    {
        enum OperationEnum : int { Sum, Muiltiply, Divide, Subtract }
        static List<Func<double, double, double>> actions = new List<Func<double, double, double>>()
        {
            { (a,b) => a+b },
            { (a,b) => a*b },
            { (a,b) => a/b },
            { (a,b) => a-b },
        };
        static void Main(string[] args)
        {
            Console.WriteLine(string.Format("{0}", actions[(int)OperationEnum.Sum](1, 3));
        }
    }
}

答案 4 :(得分:0)

不是......虽然我希望它也是如此,但它并不是那么普遍。 :\

答案 5 :(得分:0)

开关至少会更漂亮:)并且代码将更有效(数组查找等)。此外,当您错过某些选项等时,编译器和IDE可以给您一些提示。

但正如我的评论所述,这不仅仅是一般代码改进的答案。

switch (operation)
{
    case OperationEnum.Sum:
        return aggregateValue + sourceValue;
    case OperationEnum.Subtract:
        return aggregateValue - sourceValue;
    case OperationEnum.Multiply:
        return aggregateValue * sourceValue;
    case OperationEnum.Divide:
        return aggregateValue / sourceValue;
    default:
        throw new InvalidOperationException("Unsupported Aggregation Operation");
}

答案 6 :(得分:0)

这应该这样做,但是,我相信switch语句会更有效率。

private double Evaluate(string expression)
{
    return (double)new System.Xml.XPath.XPathDocument
    (new System.IO.StringReader("<r/>")).CreateNavigator().Evaluate
    (string.Format("number({0})", new
    System.Text.RegularExpressions.Regex(@"([\+\-\*])")
    .Replace(expression, " ${1} ")
    .Replace("/", " div ").Replace("%", " mod ")));
}

OR

private double Evaluate(string expression)
{
    System.Data.DataTable table = new System.Data.DataTable();
    table.Columns.Add("expression", string.Empty.GetType(), expression);
    System.Data.DataRow row = table.NewRow();
    table.Rows.Add(row);
    return double.Parse((string)row["expression"]);
}

则...

public double PerformOperation(double x, double y, string op)
    {
        string exp = string.Format("{0} {1} {2}"
                    , x.ToString()
                    , op, y.ToString());

        return Evaluate(exp);
    }

答案 7 :(得分:0)

我不确定这个的上下文,但是你可以使用一个执行所需操作的委托传递到你的“PerformOperation”方法而不是enum。但是,如果您使用此方法,您可能甚至不需要静态方法。另一个好处是您不必关心不支持操作的特殊情况,支持任何操作。这是一个简单的例子:

namespace Example
{
    using System;

    public delegate double Operation(double first, double second);

    public static class Operations
    {
        public static readonly Operation Sum = (first, second) => first + second;
        public static readonly Operation Subtract = (first, second) => first - second;
        public static readonly Operation Multiply = (first, second) => first * second;
        public static readonly Operation Divide = (first, second) => first / second;
    }

    class Program
    {
        static void Main(string[] args)
        {
            double seed = 0;
            double aggregateValue = 0;

            aggregateValue = PerformOperation(Operations.Sum, 5, 10);
            Console.WriteLine(aggregateValue);

            aggregateValue = PerformOperation(Operations.Multiply, aggregateValue, 10);
            Console.WriteLine(aggregateValue);

            aggregateValue = PerformOperation(Operations.Subtract, aggregateValue, 10);
            Console.WriteLine(aggregateValue);

            aggregateValue = PerformOperation(Operations.Divide, aggregateValue, 10);
            Console.WriteLine(aggregateValue);

            // You can even pass delegates to other methods with matching signatures,
            // here to get the power of ten.
            aggregateValue = PerformOperation(Math.Pow, aggregateValue, 10);
            Console.WriteLine(aggregateValue);

            Console.ReadLine();
        }

        private static double PerformOperation(Operation operation, double aggregateValue, double sourceValue)
        {
            return operation(aggregateValue, sourceValue);
        }
    }
}

使用这种方法,您可以轻松地使用新操作扩展程序,甚至无需触及PerformOperation方法。这可以采取进一步的步骤,但不知道上下文,很难描述。