Can I pass a method as a parameter? - c#

I am developing several plugin methods that generate a string, and pass it back to my main method. From here, I can then come up with a sequence number. However, I want to avoid integrating the plugin into my main program - basically anything that forces me to change my main program in any way to recognise this plugin is off-limits.
So - in my main program, I generate a string, then match it with other matching strings to figure out the sequence number. The trouble is that I need to know the format of this string so I know where to input this number.
I was thinking about possibly passing in a method that knows the matching functions for this string, but I'm not sure how I can pass a method from one program to another.
I have found this question, but this only appears to be within the same program.

In C#, you can either pass a method as the argument of another method provided that it returns something which the recipient method is expecting. Thus, given this:
public int Foo(){ ... }
public void Bar(int i) { ... }
You can do something like so: ...Bar(this.Foo());
However, I think that what you are after actually are delegates, which are essentially function pointers. This would allow you to call the method to which the delegate points to from some other method.
As a side note, you could consider looking into the Strategy Design Pattern. This pattern allows you to essentially determine which behaviour (logic) to call at run time.

First of all for your case you dont need to pass the method. You can make the method public and access in another program in same namespace like:- ClassObject.Method();... here object should be of class where your method is defined
You can Contain the Return value of function as a parameter while calling if thats what you are trying(like:- testapp(Square(x)) if the type of param is same as of method's Return Type .. In another Case Delegates could be useful.

Related

How to create a void method that outputs an integer and have the method divide the data passed to it by 2?

I'm really brand new at this and still learning C#. I've had a hard time trying to look for a good example to the assignment I'm working on.
So you can see exactly what I've been asked, here is the verbatim text of my assignment:
Perform these actions and create a console app that includes the
following:
Create a class. In that class, create a void method that outputs an integer. Have the method divide the data passed to it by 2.
In the Main() method, instantiate that class.
Have the user enter a number. Call the method on that number. Display the output to the screen. It should be the entered number, divided by two.
Create a method with output parameters.
Overload a method.
Declare a class to be static.
So far I created a class. In the Main() method, instantiate that class. I apologize in advance if the answer is on here. Point me to the direction if it is. Thank you.
in my main() program:
class Program
{
static void Main(string[] args)
{
MathMethod mathMethod = new MathMethod(); //Instantiate
}
}
my MathMethod.cs:
class MathMethod
{
public void Operator()
{
int num1 = 6;
int num2 = 9;
}
public void Output(int number1, int number2)
{
int value =
}
I'm not going to do your assignment but I'm happy to provide pointers for you to assemble into a solution for your assignment
The assignment text contains some confusing phrasing. I'd say "call the method on that number" should read "call the method, passing that number" - calling a method "on" is something different, and somewhat implies that you're expected to write an extension method (which I can't quite believe is a requirement for an assignment of this level)
It also asks things of you that I'm not sure I'd ask of a new learner but hey ho, we are where we are
For the most part I'd say that your particular problem here has been answered by Piotr; their answer adds rather than your requirement to divide but I'm sure you can work that one out. Also, their answer takes both operands to the operation but your assignment asks you to create a method that takes just one number, and halves it so your method won't have 3 parameters like Piotr's does, it will have 2
In the Main() method, instantiate that class.
This is done
Have the user enter a number.
Use a Console.WriteLine to prompt the user to do something, then use a Console.ReadLine to read their typing into a string variable
You'll also need to convert the string to an int; take a look at int.Parse which is easy to use.
You can look at upgrading to int.TryParse later, which is a more robust option that doesn't crash if the user enters garbage that can't be interpreted as a number. Amusingly/interestingly, TryParse works in the same way as what your assignment is asking you; it uses an out parameter to make the parsed number available. The reason why it uses an out is because it also returns a boolean indicating success or not so you can act accordingly; this is a more valid use case for out than what your assignment asks you to consider because TryParse has a genuine need to return two things (the bool of whether it succeeded and the value it parsed if it did succeed). Your requirement is more artificial and uses an out for the sake of academic point; please don't take away from it that out is a good thing to be used often. It (and it's sibling ref) are terrible things that we try to minimize usage of wherever possible.
Once this assignment is over, strive to avoid ever having to use out again until you're fully aware of the implications; once newbies start to think "this is how I return multiple things from a method" they start putting out everywhere. No; the "a method can only return one thing" is perfectly possible to work with, you just make the one thing a method can return an object that holds the multiple things you want to return and then return one of that object. This is Object Oreinted programming after all!
I use out so seldom I don't recall a particular use case in the last 10 years of coding I've done, other than academically contrived examples on SO, also imploring people not to use it
Call the method on that number.
It means call the method, passing the parsed number as the argument
Display the output to the screen.
Piotr's demonstrated this
Create a method with output parameters.
This seems like a tip for how you should achieve step 2; you'll have already done this by the time you get here
Overload a method.
Overloading is providing two or more methods in the same class, that are named the same. The compiler chooses which one to use based on some difference it finds in the argument
This is an example of set of overloads:
void Halve(int number, out int result)
void Halve(int number, int howManyTimes, out int result)
void Halve(double number, out double result)
Overloads can differ by number of arguments, type of arguments, or both. Incidentally, the first two above are what I would perhaps recommend for your assignment; provide a method Halve that divides by 2 just once, and then provide another method that takes an additional number that is how many times to do the divide.
For extra style points you can have the Halve that divides just once call the method that divides N times, passing 1 for the N argument
Declare a class to be static.
Oof, I do wish educators wouldn't promote static. It's such a pain in the ass because it undoes all the good work we're doing trying to get you to think in terms of multiple instances of the same type of object. It also makes me wonder more about the earlier mentioned extension method
I'd "bypass" this one by making the Program class that holds your Main method as static
If you need to return value from method you can either:
Use return kind (which is forbidden in your assigment)
Use ref / out arguments (which allows, for example, returning more than one value without using Tuples).
Example (written without testing!):
// out - means that parameter will be passed out of method
public void Output(int number1, int number2, out int result)
{
result = number1 + number2;
}
public void AddNumbers()
{
int ret; // Need to define variable to hold the result
Output(2, 5, out ret); // Actual call. Note the out keyword
Console.WriteLine("2 + 5 = " + ret);
}

Validate Parameters at compile-time?

Let's say I have a simple function:
public static int NewNumber(int lowestValue, int highiestValue) {}
I would like to have some a compiler check if parameters are correct. For example, in this case, the developer could mistakenly (or on purpose) call the method like this:
NewNumber(5, -5);
which is wrong in this case - The developer lied.
Sure I could make a simple check inside the method:
public static int NewNumber(int lowestValue, int highiestValue) {
if (highiestValue <= lowestValue) {
//Error
}
}
... and it would work just perfectly. However, I'm curious if there is anything the developer can do in this case to restrict such behavior without additional checking in the method itself.
EDIT: Found out the solution but nonrelated to the C#
Since I'm working in Unity I end up with writing custom inspector so values can be entered correctly in the Unity Inspector itself, thus eliminating unnecessary checks (and slowing the performance) when calling the method many times per second.
This I don't believe is possible. Consider this situation,
NewNumber(x, y);
What's x and y? The compiler doesn't necessarily know what the input is (e.g. x = Int32.Parse(Console.ReadLine());).
You gave hard-coded examples, and perhaps you might only use the function with hard-coded values, but the compiler only knows that 5 and -5 are integers and integers can be a literal 5, -5, etc or a variable var a = 5;
I don't think there is a compiler related parameter argument check. But it is always better to have your parameter check within your method (responsibility of your method to take care the parameter) and document it better so, the caller knows what data it should pass to your method.

C# - take method as an argument without specifying args

I have a method that needs to take the function and its owner class as the input arguments and then to proceed with its names with reflection. Of course I could take a couple of strings as the input args, so the method would look like this:
void Proceed(string className, string methodName)
{
Console.WriteLine($"{className}.{methodName} called");
//...
}
and would be called like this:
Proceed(nameof(Foo), nameof(Foo.Bar));
But I wonder if there is any way to avoid writing the nameof keyword every time I am trying to call the method. To me something like Proceed<Foo>(f => f.Bar) would look a lot nicer.
I suppose this could be solved with expressions. The problem I face is that if method Bar has arguments, you have to specify them explicitly when calling the method (which seems excessive in my case where you only going to need the name of the method later).
So, the best solution I managed to find is this one:
void Proceed<T>(Expression<Func<T, Action<object, object>>> expression)
{
//...
}
Yet it still specifies the argument method's signature in its own args and therefore is not generic enough.
I wonder if there is some way to pass the function as an argument without specifying its arguments (provided I am only going to need its name later, just like nameof keyword does).
I think you are looking for the usage of an event or delegate.
You can look up more information regarding those 2 online. The idea is that they store some methods with the same arguments so that later it knows what kind of arguments you need to call.
Yes, use the Delegate keyword.
See the answer here.

way to define functions in parameters in order to pass one, out of two, functions as an argument

My program had a simple function newline() that would provide an int value to a int variable x.
public void autowordwrap(string wrapthisword)
{
//some code that does things irrelevant to this problem, with the string
x=newline();
//assume x is already declared properly
//do something with value from x
}
Problem started when I introduced a new function sameline()
I want to be able to do any one of these conveniently, at a time:
public void autowordwrap(string wrapthisword)
{
x=newline();
}
or,
public void autowordwrap(string wrapthisword)
{
x=sameline();
}
So, I thought of trying this:
public void autowordwrap(string wrapthisword, Func<void,int> linefunc)
{
x=linefunc;
}
which I can later call on requirement as:
autowordwrap(mystring,newline());
or,
autowordwrap(mystring,sameline());
But it is not quite working out for me!
It says keyword 'void' cannot be used in this context
Problem is:
What I want to do should be simple enough but I'm not quite understanding how it works. I understand that Action<> works for functions without return type and Func<> works for function with a return type.[Reference-1].
What I've gathered so far is:
MSDN tells me: To reference a method that has no parameters and returns void (or in Visual Basic, that is declared as a Sub rather than as a Function), use the Action delegate instead.
Since my newline() function is defined as an int-datatype, and it returns an integer after running, I thought Action<> didn't suit my needs.
This answer has what I need but for the life of me, I couldn't make it work for my specific purpose.
Problem Breakdown
I have two functions newline() and sameline()
I wish to pass any ONE out of the TWO of them as an argument of the function autowordwrap()
which means, in my Main Program, I will be using autowordwrap(somestring, newline()); or autowordwrap(somestring, sameline()); wherever necessary!
both newline() and sameline() are int-datatype functions who return integer value upon being called. For the sake of this problem, lets store it in int x
while trying to solve this, I'm assuming that using Func is used to pass nothing onto the function as an argument while calling example: newline(void) and the int part is used to define the function newline() or any function represented by delegate Func<> as one which returns an int value.
I have realized that what I have seemed to learn must be fundamentally flawed somehow somewhere. Please enlighten me. Reference links would be very helpful too.
Solving this problem in any way is acceptable. You do not need to do this in the way that I may have unintentionally rigidly outlined. Please feel free to explore creative solutions as long as they fulfill the intended purpose in C#
Yes, I acknowledge that THIS is a possible duplicate of this question but I couldn't make much sense of the helpful answer posted over there. Assuming, this will be the case for many future readers, I'm making this question and linking it to that question so that it may be helpful to people who'll face this same problem in the future.
Endnote:
This Question has been solved! The marked answer lays down the way for doing this and there is also some great explanation in the answers. If you are facing some errors while solving a similar question of this nature, you might be able to fix those my looking over screenshots of my own errors. They're here in the revision section no.4
Func<T> has to return some thing, it cannot be void, you have to use Action<T>, if you don't want to return anything.
and if you don't want to pass any input argument to the Func<T>, then you just need one parameter which is return type like:
Func<int> linefunc
you cannot define input type parameter for Func<T,TResult> as void, instead of that just remove the input type parameter of it,
your method definition would look like :
public void autowordwrap(string wrapthisword, Func<int> linefunc)
{
x=linefunc();
}
and call it like:
autowordwrap(mystring, newline);
autowordwrap(mystring, sameline);
You're very nearly there. There are a couple of issues.
First, from your code you appear to be passing the result of your functions in;
autowordwrap("foo", newline());
In this code, C# will invoke the newline function, getting a result. It will then pass the result of that function -- your int -- as the second parameter to autowordwrap.
What you're wanting to do is pass in the un-invoked function itself;
autowordwrap("foo", newline);
So long as the signature of the newline function is compatible with the signature required by autowordwrap, you'll be able to invoke that function inside autowordwrap.
The second part isn't so much the difference between Func<> and Action<>, but about the generic parameters.
The signature you want is a function which takes no parameters and returns an int. So it's reasonable to try
Func<void, int>
but actually, Func<> can take any number of generic types. All but the last are parameters; the last is the return value. So
Func<string, string, int>
corresponds to a method like
public int MyFunction(string s1, string s2) { return 0; }
What you're trying for is a function of no parameters, equivalent to
public int MyFunction() { reutrn 0; }
So the signature you're looking for is
Func<int>
That is, a function of no parameters, returning int. For clarity,
Action<int>
takes one integer parameter and reutrns nothing, equivalent to
public void MyAction(int myParam) { }
--
Oh, and to clarify;
Func<void, int>
Doesn't work because it's equivalent to writing this in C#
public int MyFunction(void x) {}
which is like saying 'a function which takes one parameter, which is a variable of type 'void''. That doesn't make sense, hence the compiler error.
Since your function doesn't need a delegate, it needs an int, you're better off avoiding delegates altogether, just pass the int value, and do this:
public void autowordwrap(string wrapthisword, int separator)
{
//some code that does things irrelevant to this problem, with the string
// if you need it in "x"
x=separator;
//do something with value from x
}
autowordwrap(mystring,newline());
// or
autowordwrap(mystring,sameline());
The general idea for creating clean high quality code is for a function to accept the value(s) it requires to do its specific task, and not some complex input that is "bigger" then that.

Understanding Delegates Generics

I am going through a course on developing extensible software on pluralsight and in one of the slides, this code comes up. My understanding of delegate so far has been that it is used to point to other methods but i cannot figure out what's the purpose of delegate here and if anyone can point me in the right direction please.
As written there, it isn't very useful... They could have used Action<OrderItemProcessedEventArgs> and it would have been equivalent. (Action<> is the generic delegate for methods that don't return anything. Its official description is something like Encapsulates a method that has a single parameter and does not return a value.)
The delegate as written (and the Action<OrderItemProcessedEventArgs>) represent a method that returns void (so that doesn't return anything) and that accepts a single OrderItemProcessedEventArgs argument. So for example:
public void MyMethod(OrderItemProcessedEventArgs arg)
{
}
would be a method compatible with that delegate.
Now... that big block of code creates a CommerceEvents, that seems to be a container of events (not C#-events, directly delegates), that some pieces of code can "subscribe" by assigning methods to the properties (OrderItemProcessed in this case). Some other code, when necessary, will call OrderItemProcessed(someOtherItemProcessedEventArgs), passing a "descriptor" of why the "event" was executed (the OrderItemProcessedEventArgs class)
The delegate you have declared, represents any method which takes a generic T argument and returns void. T can be any class. You can also look into Func and Action delegates which are also generic in nature.

Categories

Resources