Passing code as parameter C# - c#

I'm trying to pass a reference to a function as a parameter
It's hard to explain
I'll write some example pseudo code
(calling function)
function(hello());
function(pass)
{
if this = 0 then pass
else
}
hello()
{
do something here
}
Sorry if it does not make much sense
But I'm trying to reduce used code and I thought this would be a good idea.
How can I do this in C#?

You can pass code to a method by using delegates, for example, the Action delegate:
void MyFunction(Action action)
{
if (something == 0)
{
action();
}
}
void Hello()
{
// do something here
}
Usage:
MyFunction(Hello);

I'm trying to pass a reference to a function as a parameter
It's hard to explain
It may be hard to explain, but it is very easy to implement: the code below calls MyFunction passing it a parameterized piece of code as a parameter.
static void MyFunction(Action<string> doSomething) {
doSomething("world");
}
static void Main(string[] args) {
MyFunction((name) => {
Console.WriteLine("Hello, {0}!", name);
});
}
You can use delegate types provided by the system (Action and Func) or write your own.

Here is an example:
using System;
public class Example
{
public void Method1(Action hello)
{
// Call passed action.
hello();
}
public void Method2()
{
// Do something here
}
public void Method3()
{
Method1(Method2);
}
}

Related

C# beginner - Callback in the same function

I'm pretty sure that is possible (at least in java it is) and I'm C# beginner.
So I have a function which includes a callback (notify some other method that some work is finished).
I don't want to call another function because I'm losing a parameter there (and can't pass parameters in callback functions). How can I do everything in the same function?
What I'm doing now:
public static Tween Play(Tween tweenToPlay)
{
return tweenToPlay.Play().OnComplete(RewindCallback);
}
private static void RewindCallback()
{
// Execute some code after Tween is completed
}
What I actually want:
public static Tween Play(Tween tweenToPlay)
{
return tweenToPlay.Play().OnComplete(/*Create a function that will execute here*/);
}
Do you mean a lambda expression, like this?
public static Tween Play(Tween tweenToPlay)
{
return tweenToPlay
.Play()
.OnComplete(() => {
// Do stuff
});
}
You just want an anonymous method?
public static Tween Play(Tween tweenToPlay)
{
return tweenToPlay.Play().OnComplete(() =>
{
//... your code
});
}
Anonymous/lambdas are shorter to write, but depending on the complexity - you might want to use a full fledged class as follows.
Create a class with a field for that variable and an appropriate callback function.
When you want to subscribe to the callback - create an instance of that class with that field set, and set the callback to the callback in that instance.
Example:
class Temp
{
public Tween Tween1;
public void RewindCallback()
{
// Execute some code after Tween is completed
}
}
And usage:
Temp temp;
public Tween Play(Tween tweenToPlay)
{
temp = new Temp { Tween1 = tweenToPlay };
return tweenToPlay.Play().OnComplete(temp.RewindCallback);
}

Call Method based on Type of Parameter

I have an object that can be of type AudioRequest or VideoRequest. Both classes inherit from Request. I have this class:
public static DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
I want to be able to call DoThings.HandleRequest(r) where r can be either a VideoRequest or AudioRequest and have it call the correct one. Is that possible? I have no control over the *Request classes, so I can't do anything to them. I do have control of the DoThings class and the code that calls HandleRequest. This is the code that calls it, it is WebAPI:
public Response Post(Request input)
{
return DoThings.HandleRequest(input);
}
The code above gives the error Argument 1: cannot convert from 'Request' to 'AudioRequest'.
The original code that I was cleaning up had this:
if (input.GetType() == typeof(AudioRequest))
{
var audioRequest = (AudioRequest)input;
DoThings.HandleRequest(audioRequest);
}
else if (input.GetType() == typeof(VideoRequest))
{
var videoRequest = (VideoRequest)input;
DoThings.HandleRequest(videoRequest);
}
But I figured there was a cleaner way to do this.
Based on the information you've provided so far, your question appears to be a duplicate of How to call a function dynamically based on an object type. I agree with the answer, that the fact that you want to do this suggests you should rethink the design. But, you can use dynamic to accomplish what you want.
Here's a simple console program that demonstrates the basic idea:
class Program
{
static void Main(string[] args)
{
A b = new B(), c = new C();
M(b);
M(c);
}
static void M(A a)
{
WriteLine("M(A)");
M((dynamic)a);
}
static void M(B b)
{
WriteLine("M(B)");
}
static void M(C c)
{
WriteLine("M(C)");
}
}
class A { }
class B : A { }
class C : A { }
The output is:
M(A)
M(B)
M(A)
M(C)
As you can see, in each case the M(A) method is called first, and then the appropriate M(B) or M(C) overload is called from M(A).
In your own example, this could look something like this:
public static DoThings
{
public static void HandleRequest(Request r)
{
// Dynamic dispatch to actual method:
HandleRequest((dynamic)r);
}
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
Note that dynamic does incur a run-time cost, particularly the first time a method is called with a given run-time type. But depending on the frequency and complexity of these "requests", using dynamic could be the cleanest way out of the current situation.
C# will call the appropriate function that matches the arguments and their types.
That being said, both of your functions accept AudioRequest, I believe one of those should accept a VideoRequest.
public static DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
If for some reason you must have two different functions that take only AudioRequest you can differentiate between two function with an extra parameter
public static class DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(AudioRequest r, bool UseAlternativeMethod)
{
// Do other things.
}
}
Simply having a second parameter will call the second method regardless of it's value.
This isn't a best practices solution as you'd rather discriminate between them by accurately renaming the method name to be accurate but in practice you don't always have a choice.

Different methods using Functors/Delegates in c#

I have a method that I call multiple times, but each time a different method with a different signature is called from inside.
public void MethodOne()
{
//some stuff
*MethodCall();
//some stuff
}
So MethodOne is called multiple times, each time with a different *MethodCall(). What I'm trying to do is something like this :
public void MethodOne(Func<> MethodCall)
{
//some stuff
*MethodCall;
//some stuff
}
but the Methods that are called each have a different return type and different parameters. Is there a way to do this using Functors? If not, how would I go about doing this?
Thank you!
You best bet would be to use the non-generic Action type (or MethodInvoker would be the same), i.e.
public void MethodOne(Action callback)
{
//some stuff
if(callback != null) callback();
//some stuff
}
From this you can call any method by wrapping it at the caller, i.e.
MethodOne(SimpleMethod); // SimpleMethod has no parameters and returns void
MethodOne(() => MoreComplexMethod(1, "abc")); // this one returns void
MethodOne(() => { MethodThatReturnsSomething(12); }); // anything you like
etc
You cannot call a function which requires parameters without supplying them, so the answer is "no, not possible"
Also, maybe you want the following:
void MethodOne(Action a)
{
// some stuff
a();
// some stuff
}
... // somewhere in the code
MethodOne((Action)(() => { DoSomethingOther(1, 2, 3); }));
MethodOne((Action)(() => { DoSomethingEvenDifferent(1, 2, 3, 4, 5); }));
Every delegate in .Net is an instance of a class derived from Delegate. So if you really wish to pass 'any' delegate to a method, you can pass it as Delegate
To invoke it, you need to use its DynamicInvoke method.
public void MethodOne(Delegate MethodCall)
{
//some stuff
//Assuming you now have the required parameters
//or add params object[] args to the signature of this method
object res = MethodCall.DynamicInvoke(args); //args is object[] representing the parameters
//some stuff
}
But this is not recommended as DynamicInvoke is slow and it does not offer any compile time safety. Probably you should revisit your design.
This is basically not possible. You could make MethodOne generic for the return type, and use a lambda that closes over its outside block instead of parameters:
static void Main(string[] args)
{
int parameterSubst = 1;
int result = MethodOne<int>(() => parameterSubst);
string result2 = MethodOne<string>(() =>
{
string s = parameterSubst.ToString();
s += "foo";
return s;
});
}
static T MethodOne<T>(Func<T> function)
{
return function();
}
As you can see, parameterSubst is used in the passed Func<T>s, but not as a parameter.

C# function pointer?

I'm having a problem with C#, I'd like to get a pointer of a method in my code, but it seems impossible. I need the pointer of the method because I want to no-op it using WriteProcessMemory. How would I get the pointer?
Example code
main()
{
function1();
function2();
}
function1()
{
//get function2 pointer
//use WPM to nop it (I know how, this is not the problem)
}
function2()
{
Writeline("bla"); //this will never happen because I added a no-op.
}
I know this is very old, but an example of something like a function pointer in C# would be like this:
class Temp
{
public void DoSomething() {}
public void DoSomethingElse() {}
public void DoSomethingWithAString(string myString) {}
public bool GetANewCat(string name) { return true; }
}
...and then in your main or wherever:
var temp = new Temp();
Action myPointer = null, myPointer2 = null;
myPointer = temp.DoSomething;
myPointer2 = temp.DoSomethingElse;
Then to call the original function,
myPointer();
myPointer2();
If you have arguments to your methods, then it's as simple as adding generic arguments to your Action:
Action<string> doItWithAString = null;
doItWithAString = temp.DoSomethingWithAString;
doItWithAString("help me");
Or if you need to return a value:
Func<string, bool> getACat = null;
getACat = temp.GetANewCat;
var gotIt = getACat("help me");
EDIT: I misread your question and didn't see the bit about wanting to NOP a statement with doing raw memory manipulation. I'm afraid this isn't recommended because, as Raymond Chen says, the GC moves stuff around in memory (hence the 'pinned' keyword in C#). You probably can do it with reflection, but your question suggests you don't have a strong grasp of the CLR. Anyway, back to my original irrelevant answer (where I thought you just wanted information on how to use delegates):
C# isn't a scripting language ;)
Anyway, C# (and the CLR) has "function pointers" - except they're called "delegates" and are strongly typed, which means you need to define the function's signature in addition to the function you want to call.
In your case, you'd have something like this:
public static void Main(String[] args) {
Function1();
}
// This is the "type" of the function pointer, known as a "delegate" in .NET.
// An instance of this delegate can point to any function that has the same signature (in this case, any function/method that returns void and accepts a single String argument).
public delegate void FooBarDelegate(String x);
public static void Function1() {
// Create a delegate to Function2
FooBarDelegate functionPointer = new FooBarDelegate( Function2 );
// call it
functionPointer("bla");
}
public static void Function2(String x) {
Console.WriteLine(x);
}
public string myFunction(string name)
{
return "Hello " + name;
}
public string functionPointerExample(Func<string,string> myFunction)
{
return myFunction("Theron");
}
Func functionName.. use this to pass methods around. Makes no sense in this context but thats basically how you would use it
I'd wish it is useful
class Program
{
static void Main(string[] args)
{
TestPointer test = new TestPointer();
test.function1();
}
}
class TestPointer
{
private delegate void fPointer(); // point to every functions that it has void as return value and with no input parameter
public void function1()
{
fPointer point = new fPointer(function2);
point();
}
private void function2()
{
Console.WriteLine("Bla");
}
}
Actually there are real function pointers introduced in C# 9
Official Documentation
From the link:
You can define a function pointer using the delegate* syntax. The compiler will call the function using the calli instruction rather than instantiating a delegate object and calling Invoke
Example for the example in the post:
static unsafe void function1()
{
//get function2 pointer
delegate*<void> ptr = &function2;
// do something with ptr
}
Rewriting a method cannot be done directly from managed code, however the unmanaged .net profiling api can be used to do this. See this msdn article for example on how to use it.

C#: Creating an instance of an abstract class without defining new class

I know it can be done in Java, as I have used this technique quite extensively in the past. An example in Java would be shown below. (Additional question. What is this technique called? It's hard to find an example of this without a name.)
public abstract class Example {
public abstract void doStuff();
}
public class StartHere{
public static void main(string[] args){
Example x = new Example(){
public void doStuff(){
System.out.println("Did stuff");
}
};
x.doStuff();
}
}
Now, my main question would be, can this also be done in C#, and if so, how?
The Java technique is called "Anonymous inner class", and there is no equivalent in C#.
With lamba expressions and class initializers you can get the same behaviour with a bit of effort.
public class Example {
public Action DoStuff;
public Action<int> DoStuffWithParameter;
public Func<int> DoStuffWithReturnValue;
}
class Program {
static void Main(string[] args) {
var x = new Example() {
DoStuff = () => {
Console.WriteLine("Did Stuff");
},
DoStuffWithParameter = (p) => {
Console.WriteLine("Did Stuff with parameter " + p);
},
DoStuffWithReturnValue = () => { return 99; }
};
x.DoStuff();
x.DoStuffWithParameter(10);
int value = x.DoStuffWithReturnValue();
Console.WriteLine("Return value " + value);
Console.ReadLine();
}
}
One problem with this solution that I just realized is that if you were to create fields in the Example class, the lambda expressions would not be able to access those fields.
However, there is no reason that you could not pass the instance of Example to the lambda expressions which would give them access to any public state that example might hold. AFAIK that would be functionally equivalent to the Java Anonymous Inner Class.
P.S. If you are going to vote an answer down, do us all a favour and add a comment as to why you disagree :-)
Typically, problems that are solved with anonymous inner classes in Java are solved in a much cleaner fashion using delegates in .Net. Your example is a little too simplistic to determine your intent. If your intent by using the abstract class is to pass around a "behavior" think about just using an Action delegate instead.
public class StartHere{
public static void main(string[] args){
Action doStuff = () => Console.WriteLine("Did stuff");
executeSomething(doStuff);
}
public static void executeSomething(Action action)
{
action();
}
}
That can't be done in C#; you need to declare a new class type. The closest you can get in C# is probably a named nested class:
public class StartHere{
private class Foo : Example {
public override void doStuff()
{
Console.WriteLine("did stuff");
}
}
public static void Main(string[] args){
Example x = new Foo();
x.doStuff();
}
}
This is not supported in C#, and if it were up to me it shouldn't be so either.
The proliferation of inner classes in java is mainly due to the lack of delegates or lambdas, which C# has. So while this type of functionality currently is "your only hope" in java, you can usually use other mechanisms in C# to achieve the same ends. Java feels like playing the piano with one hand in this regard.
(Admittedly a lot of us have gotten quite good at this one-handed playing; and now it seems like we have to wait at least until java 8 for closures...)
Since your class represents only an action, you can use a delegate in your case, there is an existing delegate :
public delegate void Action();
This is the exact equivalent of your class.
And the déclaration of your anonymous class is even cleaner :
Action action = () => Console.WriteLine("Hello world");
action(); // invoke
you can even use closure :
public void Hello(string name)
{
Action action = () => Console.WriteLine("Hello " + name);
action(); // will call the above lambda !
}
While all good answers, most of the work arounds suggested rely on C# 3.0
So, for the sake of completeness, I'll add another solution that uses neither lambdas nor Func type (Granted that, as Matt Olenik mentioned in the comments, one could generalize the below delegates to work the same way.). For those, like me who may still be working with C# 2.0. Maybe not the best solution, but it works.
public class Example
{
public delegate void DoStuffDelecate();
public DoStuffDelecate DoStuff;
public delegate void DoStuffWithDelecate(int n);
public DoStuffWithDelecate DoStuffWithParameter;
public delegate int DoStuffWithReturnDelecate();
public DoStuffWithReturnDelecate DoStuffWithReturnValue;
}
class Program
{
static int MethodWithReturnValue()
{
return 99;
}
static void MethodForDelecate()
{
Console.WriteLine("Did Stuff");
}
static void MethodForDelecate(int n)
{
Console.WriteLine("Did Stuff with parameter " + n);
}
static void Main(string[] args)
{
var x = new Example();
x.DoStuff = MethodForDelecate;
x.DoStuffWithParameter = MethodForDelecate;
x.DoStuffWithReturnValue = MethodWithReturnValue;
x.DoStuff();
x.DoStuffWithParameter(10);
int value = x.DoStuffWithReturnValue();
Console.WriteLine("Return value " + value);
Console.ReadLine();
}
}
You are able to accomplish this with Mocking in .NET. However there is no in-language support for this feature, I think it will be available in C# 4.0. There are a number of libraries out there for Mocking, including:
Moq
RhinoMock
In short no, you have to define it as separate sub class. I think this feature is coming C# 4.0 though?
Edit: No it's not coming C# 4.0 I made that up.

Categories

Resources