Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an operator along with other parameters

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.

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;
.
.
.
like image 643
user32848 Avatar asked Jul 27 '09 19:07

user32848


People also ask

How do you call a method with parameters in another method in C#?

You can use the Action delegate type. Then you can use it like this: void MyAction() { } ErrorDBConcurrency(e, MyAction); If you do need parameters you can use a lambda expression.

How do you pass reference parameters in C#?

Passing by reference enables function members, methods, properties, indexers, operators, and constructors to change the value of the parameters and have that change persist in the calling environment. To pass a parameter by reference with the intent of changing the value, use the ref , or out keyword.

Can we pass var as parameter in C#?

It means we cannot pass a variable value as input using out parameter. Variables passed as out arguments do not have to be initialized before being passed in a method call. Even if it is initialized, this value cannot be accessed inside the method.

Is C# pass by value?

By default, C# does not allow you to choose whether to pass each argument by value or by reference. Value types are passed by value. Objects are not passed to methods; rather, references to objects are passed—the references themselves are passed by value.


2 Answers

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

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

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.

C++ invocation example:

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:

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

like image 199
Steve Guidi Avatar answered Oct 28 '22 09:10

Steve Guidi


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

C# Example:

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.

This is the C method for doing so:

bool (*operator_func)(float a, float b)
like image 29
Avihu Turzion Avatar answered Oct 28 '22 08:10

Avihu Turzion