C# 将运算符与其他参数一起传递

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1190062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:24:39  来源:igfitidea点击:

Passing an operator along with other parameters

c#c++visual-studiodelegates

提问by user32848

I have some VERY inefficient code in which many lines appear 4 times as I go through permutations with "<" and ">" operations and a variety of variables and constants. It would seem that there is a way to write the function once and pass in the operators along with the necessarily changing values and"ref" variables. What technique do I have to learn? "Delegates" have been suggested but I don't see how to use them in this manner. This is in C# 2.0, VS2005, but if the technique is generic and can be used with C++ too, that would be great.

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

Request for some code: The following appears in many guises, with different "<" and ">" signs as well as a mix of "+" and "-" signs:

请求一些代码:以下内容以多种形式出现,带有不同的“<”和“>”符号以及“+”和“-”符号的混合:

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

采纳答案by Steve Guidi

In C++, use the std::lessand std::greaterfunctors. Both of these methods inherit std::binary_function, so your generic function should accept instances of this type.

在 C++ 中,使用std::lessstd::greater函子。这两个方法都继承了std::binary_function,所以你的泛型函数应该接受这种类型的实例。

In .NET, the equivalent to std::binary_functionis Func<T, U, R>. There are no equivalents to std::lessand std::greater, but it is fairly trivial to create them. See the following example.

在.NET中,相当于std::binary_functionFunc<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; };
    }
}

Note, the above code uses the Func<>class from .NET 3.5. If this is not acceptable, consider defining you own delegate.

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

C++ invocation example:

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# invocation example:

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

EDIT: I corrected the example of the functor class as applying < or > operators to a generic type doesn't work (in the same manner as it does with C++ templates).

编辑:我更正了函子类的示例,因为将 < 或 > 运算符应用于泛型类型不起作用(与使用 C++ 模板的方式相同)。

回答by Avihu Turzion

In C# use delegates for passing the "<" and ">" operation to the code that's doing the work.

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

C# Example:

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

You should also check that the delegate you get as a paramater is not NULL.

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

This is the C method for doing so:

这是这样做的 C 方法:

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

回答by Amine Boulaajaj

After defining the Enum Operator in the Comparer class

在 Comparer 类中定义 Enum Operator 之后

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

You can make a call like this:

您可以这样拨打电话:

 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.");