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
How to Write Fast Colored Output to Console
How to Render Text in .Net in the Same Size as Browsers Does Given CSS for the Text
Handling Decimal Values in Newtonsoft.JSON
How to Create a Task (Tpl) Running a Sta Thread
How to Get the "Friendly" Os Version Name
Webclient.Downloadstring() Returns String with Peculiar Characters
No Type Inference with Generic Extension Method
Getting Full Url of Action in ASP.NET MVC
Best Way to Combine Two or More Byte Arrays in C#
Wpf Application That Only Has a Tray Icon
Passing a Single Item as Ienumerable<T>
ASP.NET Core 2.0 Authentication Middleware
How to Create Deterministic Guids