Operators as Method Parameters in C#

Operators as method parameters in C#

Well, in simple terms you can just use a lambda:

public void DoSomething(Func<int, int, int> op)
{
Console.WriteLine(op(5, 2));
}

DoSomething((x, y) => x + y);
DoSomething((x, y) => x * y);
// etc

That's not very exciting though. It would be nice to have all those delegates prebuilt for us. Of course you could do this with a static class:

public static class Operator<T>
{
public static readonly Func<T, T, T> Plus;
public static readonly Func<T, T, T> Minus;
// etc

static Operator()
{
// Build the delegates using expression trees, probably
}
}

Indeed, Marc Gravell has done something very similar in MiscUtil, if you want to look. You could then call:

DoSomething(Operator<int>.Plus);

It's not exactly pretty, but it's the closest that's supported at the moment, I believe.

I'm afraid I really don't understand the Ruby stuff, so I can't comment on that...

Passing an operator along with other parameters

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

How to pass an operator as a parameter in a clean way?

The shortest you can get without using additional methods is:

var c2 = a.Zip(b, (x, y) => x <= y);

Compiler will deduct types for x and y for you, from a and b types.

If you don't like it, you can declare helper method:

public static class DoubleExtensions
{
public static bool LessOrEqual(this double first, double second)
{
return first <= second;
}
}

and use it:

var c = a.Zip(b, DoubleExtensions.LessOrEqual);

Difference Between in Operator and Simple Value Pass c#

The following clearly explains the purpose :

passes a variable in to a method by reference. Cannot be set inside the method.

From Official DOCS:

The in modifier on parameters, to specify that an argument is passed by reference but not modified by the called method.

The only difference is that the incoming parameters value cannot be set within the method when parameters are having in operator while in normal parameters we can set whatever value we want, using in we restrict from doing that.

For example:

 public static int Add(in int number1, in int number2)
{
number1 = 2; // this will give compile time error as we cannot set it.
return number1 + number2;
}

while in normal case we can set whenever we want though in the example it does not makes sense to set but clearly explains the difference:

 public static int Add(int number1,int number2)
{
number1 = 2; // this works.
return number1 + number2;
}

So, we can say that the method parameters become immutable technically.

You can read more details about it here.

C#7 'in' parameters allowed with operator overloading

Short answer: The compiler does the right thing. Trust the compiler.

Long answer:

An overloaded operator is simply a syntactic sugar for a static method. An invocation of an overloaded operator is simply a syntactic sugar for an invocation of that method.

That is,

public static bool operator ==(S s1, S s2) { ... }

is just a syntactic sugar for something like

public static bool op_Equality(S s1, S s2) { ... }

and

if (s1 == s2)

is just a syntactic sugar for

if (S.op_Equality(s1, s2))

So whatever behaviour holds for in annotations on normal static methods and normal static method calls also holds for static methods which are operators, and static method invocations which are expressions that use those operators.

Assignment operator (=) in argument of Method Definition

They're called optional (or named) arguments. MSDN usually has these things explained pretty well:

Named and Optional Arguments (C# Programming Guide)

C# Pass bitwise operator as parameter

You can use Func<>

int MyFunc(int input1, int input2, Func<int, int, int> bitOp)
{
return bitOp(input1, input2);
}

Use like this

Console.WriteLine(MyFunc(1, 2, (a, b) => a | b));

Outputs "3"



Related Topics



Leave a reply



Submit