传递操作符和其他参数

时间:2009-07-27 19:17:50

标签: c# c++ visual-studio delegates

我有一些非常低效的代码,其中许多行出现4次,因为我通过“<”进行排列和“>”操作以及各种变量和常量。看起来有一种方法可以编写一次函数并传入运算符以及必要的变化值和“ref”变量。我需要学习什么技巧?有人建议“代表”,但我不知道如何以这种方式使用它们。这是在C#2.0,VS2005中,但如果该技术是通用的并且也可以与C ++一起使用,那就太棒了。

请求一些代码:以下出现在许多伪装中,具有不同的“<”和“>”标志以及“+”和“ - ”标志的混合:

if (move[check].Ypos - move[check].height / 200.0D < LayoutManager.VISIO_HEIGHT - lcac_c.top)
{
  move[check].Ypos = move[check].Ypos + adjust;
.
.
.

3 个答案:

答案 0 :(得分:11)

在C ++中,使用std::lessstd::greater仿函数。这两种方法都继承std::binary_function,因此您的泛型函数应该接受此类型的实例。

在.NET中,等同于std::binary_function的是Func<T, U, R>std::lessstd::greater没有等价物,但创建它们相当简单。请参阅以下示例。

static class Functor
{
    static Func<T, T, bool> Greater<T>()
        where T : IComparable<T>
    {
        return delegate(T lhs, T rhs) { return lhs.CompareTo(rhs) > 0; };
    }

    static Func<T, T, bool> Less<T>()
        where T : IComparable<T>
    {
        return delegate(T lhs, T rhs) { return lhs.CompareTo(rhs) < 0; };
    }
}

注意,上面的代码使用.NET 3.5中的Func<>类。如果这是不可接受的,请考虑定义自己的代理。

C ++调用示例:

void DoWork(const std::binary_function<int, int, bool>& myOperator,
            int arg1, int arg2)
{
    if (myOperator(arg1, arg2)) { /* perform rest of work */ }
}

void main()
{
    DoWork(std::less<int>(), 100, 200);
    DoWork(std::greater<int>(), 100, 200);
}

C#调用示例:

void DoWork(Func<int, int, bool> myOperator, int arg1, int arg2)
{
    if (myOperator(arg1, arg2)) { /* perform rest of work */ }
}

void main()
{
    DoWork(Functor.Less<int>(), 100, 200);
    DoWork(Functor.Greater<int>(), 100, 200);
}

编辑:我将仿函数类的示例更正为应用&lt;或者&gt;泛型类型的运算符不起作用(与C ++模板的运行方式相同)。

答案 1 :(得分:2)

在C#中,使用委托将“<”和“>”操作传递给正在执行工作的代码。

C#示例:

public delegate bool BooleanOperatorDelegate(int a, int b)

class OperatorsImplementer {
    public bool OperatorLess(int a, int b) {
         return a < b;
    }
}

class AnotherOperatorsImplementer {
    public bool OperatorLess(int a, int b) {
         return (a + 1) < (b - 1);
    }
}

class OperatorUser {
    int DoSomethingObscene(int a, int b, BooleanOperatorDelegate operator) {
        if (operator(a, b)) {
            return 5;
        }
        else {
            return -5;
        }
    }
}

您还应该检查作为参数获得的委托是不是NULL。

这是执行此操作的C方法:

bool (*operator_func)(float a, float b)

答案 2 :(得分:0)

在Comparer类中定义Enum运算符后

     public static class Comparer
{
    public static bool IsTrue<T, U>(T value1, Operator comparisonOperator, U value2)
                where T : U
                where U : IComparable
    {
        switch (comparisonOperator)
        {
            case Operator.GreaterThan:
                return value1.CompareTo(value2) > 0;
            case Operator.GreaterThanOrEqual:
                return value1.CompareTo(value2) >= 0;
            case Operator.LessThan:
                return value1.CompareTo(value2) < 0;
            case Operator.LessThanOrEqual:
                return value1.CompareTo(value2) <= 0;
            case Operator.Equal:
                return value1.CompareTo(value2) == 0;
            default:
                return false;
        }
    }

    public enum Operator
    {
        GreaterThan = 1,
        GreaterThanOrEqual = 2,
        LessThan = 3,
        LessThanOrEqual = 4,
        Equal = 5
    }
}

你可以这样打电话:

 if (IsTrue(var1, Operator.GreaterThanOrEqual,  var2))
    Console.WriteLine("var1 is greater than var2");
 else
    Console
        .WriteLine("Unfortunately var1 is not greater than or equal var2. Sorry about that.");