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);
}
Related
I have a class that takes an Action for the constructor, let's say class A.
public class A
{
public A(Action action) {...}
}
and I instantiate it.
class Program
{
void Main()
{
A a = new A(() => { DoSomethingWith(x); });
}
}
The question is: How can I refer to 'a' in my action? In other words, how can I replace 'x' with 'a'?
I tried 'this' keyword but it refers to Program.
By the way, I can not use other inputs for my constructor, because the actions are very random in this project.
a isn't fully constructed until the constructor runs. That means that it isn't available inside the Action delegate at that point. If you want, you can create a different type of Action delegate:
public class A
{
public A(Action<A> myAction)
{
myAction(this);
}
}
public class B
{
public B()
{
var myA = new A((a) => { DoSomethingWithA(a); });
}
public void DoSomethingWithA(A a)
{
}
}
That allows it to be called with itself as an argument. The straight Action won't work though because you can't capture a before it is fully constructed.
This does seem to be an X-Y problem though, and I would avoid doing this if possible because it is difficult to tell if DoSomething is using a fully initialized A before the action is called, which can leave your object in an undetermined state. There are uses, just be careful.
As pointed out, you can't assign the action in the constructor because a has not been constructed yet. Don't confuse assigning the action with running it. You probably want to run the action at a different time to when you create a.
Without necessarily condoning the approach (it's a bit ugly and there's probably a better way to achieve your ends), you could do something like this instead:
public class A
{
Action<A> MyAction
public A(Action<A> action)
{
MyAction = action;
}
public void DoMyAction()
{
MyAction(this);
}
}
class Program
{
void Main()
{
var a = new A((x) => { DoSomethingWith(x); });
a.DoMyAction();
}
}
so I'm looking for a way to call a method in an application externally from a dll. (see example below) This is what I'm trying however it's a) not working and b) if it was working i have a feeling that calling DynamicInvoke is going to be painfully slow.
first all if I did want to do it this way how do I deal with returns types as currently this will errors saying callthisexternally() has wrong return type.
is there a better way to do this?
--- within a a dll ---
public class mydll
{
// etc.. blah blah
public object callfromdll(string commandName, int requiredArgs, Delegate method)
{
// do stuff
// now invoke the method
return method.DynamicInvoke(method.Method.GetParameters().Select(p => p.ParameterType).ToArray());
}
}
-- within an application that's refrancing the above dll --
public someclass
{
// etc.. stuff here
mydll m = new mydll();
m.callfromdll("callthisexternally", 0, new Action(callthisexternally));
// the function to be called externally
public string callthisexternally()
{
// do stuff
return "i was called!";
}
}
Without more details of what callFromDll is supposed to do you can do this simply with a Func Delegate
public class mydll
{
// etc.. blah blah
public T callfromdll<T>(string commandName, int requiredArgs, Func<T> method)
{
// do stuff
// now invoke the method
return method();
}
}
If your do stuff was doing something to generate a int you just need to use the correct method siginature.
public class mydll
{
// etc.. blah blah
public T callfromdll<T>(string commandName, int requiredArgs, Func<int, T> method)
{
int x = SomeComplexFunction(commandName, requiredArgs);
return method(x);
}
}
-- within an application that's refrancing the above dll --
public someclass
{
public void test()
{
// etc.. stuff here
mydll m = new mydll();
var result = m.callfromdll("callthisexternally", 0, new Func(callthisexternally));
//result contains "i was called, and my result was #" and where # is replace with the number passed in to callthisexternally
}
// the function to be called externally
public string callthisexternally(int x)
{
// do stuff
return "i was called, and my result was " + x;
}
}
Now your DLL will pass in the value it calculated for x in to the function you passed in and it will give you the result from that function.
I'd just like to add that using DynamicInvoke is, as you suspected, very slow and should be avoided if possible:
What is the difference between calling a delegate directly, using DynamicInvoke, and using DynamicInvokeImpl?
Not exactly sure what your trying to do here, maybe your new to C# so.
Do you try to reference a dll that you didnt wrote?, its ok just add a reference to the dll in your project. If written also in c# it usually works.
Remind that there are tons of dll's as part of SDK's that can be included that way to suit your project. Here a video to explain it https://www.youtube.com/watch?v=gmz_K9iLGU8
If you like to execute another program externally
using System.Diagnostics;
class Program
{
static void Main()
{
// Use Process.Start here.
Process.Start("C:\\HitchHickersGuide.exe /Towl /42");
}
}
I have been using javascript and I made a lot of use of functions inside of functions. I tried this in C# but it seems they don't exist. If I have the following:
public abc() {
}
How can I code a method d() that can only be called
from inside the method the method abc() ?
I wouldn't worry so much about the restriction of access to a method on the method level but more class level, you can use private to restrict access of the method to that specific class.
Another alternative would be to use lambdas/anonymous methods, or if you're using C# 4.0, Action/Tasks to create them inside your method.
An example of an anonymous method using a delegate (C# 1/2/3/4) for your specific example (incl. I need an action that can take a string parameter and return a string?) would be something like this:
delegate string MyDelegate(string);
public void abc() {
// Your code..
MyDelegate d = delegate(string a) { return a + "whatever"; };
var str = d("hello");
}
.. using C# 3/4:
public void abc() {
// Your code..
Func<string, string> d = (a) => { return a + "whatever"; };
var str = d("hello");
}
.. using a more ideal solution through private method:
private string d(string a)
{
return a + "whatever";
}
public void abc()
{
// Your code..
var str = d("hello");
}
Based on your comment for another answer: I would just like to have this at the bottom of the method and then call it from some earlier code.
This won't be possible, you would need to define a variable for your method using either delegates or Actions and so it would need to be fully initialised by time you call it. You wouldn't then be able to define this at the bottom of your method. A much better option would be to simply create a new private method on your class and call that.
It is not the way to define classes, but you could do:
public abc() {
Action d = () => {
// define your method
};
d();
}
You cannot declare a method inside another method, but you can create anonymous functions inside methods:
public void abc()
{
Action d = () => { ... };
// ...
d();
}
... that can only be called from inside the method the method abc() ?
The method can only be called if you have a reference to it. If you don't store the reference elsewhere then you should be fine.
how can I pass and return a string to the action?
Use a Func instead of an Action:
Func<string, string> d = s => {
return s + "foo";
};
The reason I would like to do this is to make my code more readable.
It's good to try to make your code more readable but I think this change will make it less readable. I suggest you use ordinary methods, and not anonymous functions. You can make them private so that they cannot be called from outside your class.
Use action delegates. More effective than you did.
public abc() {
Action <int> GetInt = (i) =>
{
//Write code here
Console.Writeline("Your integer is: {0}", i);
};
GetInt(10);
}
Action is a delegate so you can give parameter as a method, not variable. Action delegate encapsulates a method that has no parameters and does not return a value. Check it from MSDN.
Yes, they are called delegates and anonymous methods.
Delegate signatures must be predefined outside of the method for the body to be assigned, so it's not exactly like a function. You would first declare a delegate:
class MyClass {
public delegate boolean Decider(string message);
/* ... */
}
And then in MyClass.MyMethod you can say Decider IsAllLowerCase = /* method name or anonymous method */; and then use it with var result = IsAllLowerCase(s);.
The good news is that .NET already has delegate definitions for most signatures you could possibly need. System.Action has assorted signatures for methods which do not return anything, and System.Func is for the ones that do.
As shown elsewhere,
Action<int, string> a = (n, s) => { for(var i=0; i<n; i++) Console.WriteLine(s);};
Allows you to call a( /* inputs */ ); as if it was a local variable. (stuff) => { code } is "lambda expression" or an anonymous method, you can also just pass a name of a method (if the signature matches):
Action<string> a = Console.WriteLine;
If you want to return something, use Func:
Func<bool, string> f = (b) => { return b.ToString(); };
Allows you to call var result = f(b); in the same way.
As a footnote, delegates are a fun part of C#/.NET but usually, the way to control access is to make another method inside your class, and declare it private. If your issue is name conflicts, then you might want to refactor. For example, you can group methods in another class declared inside your original class (nested classes are supported) or move them to another class entirely.
You can use action delegates
public abc() {
Action action = () =>
{
//Your code here
}
action();
}
Edit: To pass parameter
public abc() {
Action <string>action = (str) =>
{
//Your code here
};
}
action("hello");
Using Func to return a value
public void abc() {
Func<string, string> func = (str) => { return "You sent " + str; };
string str = func("hello");
}
You CAN create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
Then yu can call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
I have a program that will need to run different methods depending on what I want it to talk to, and I want to know if there is a way to store some sort of method pointer or something of that sort in an array. So I want an array where each element would be something like this:
[Boolean: Do_this?] [Function_pointer] [Data to pass to the function]
So basically, I can put this into a for loop and not call each function individually. Another block of code would fill in the Boolean of whether to run this function or not, and then my for loop would go through and run the function with its appropriate data if the Boolean is true.
I know delegates are similar to function pointers, but if that is the answer here, I'm not entirely sure how I would construct what I want to construct.
Is this possible in C#?
Sure is, although, to do it this way, you need all methods to have the same signature:
Lets say you had two methods:
public int Moop(string s){ return 1; }
public int Moop2(string s){ return 2; }
You could do:
var funcs = new Func<string, int>[]{ Moop, Moop2 };
And to call:
var val = funcs[0]("hello");
You could declare a specific object type to hold in a delegate, a flag that indicates whether to do that or now and the data. Note that what you are describing is very similar to events as they are also defined by a callback and some event data.
The skeletal model would look something like this, assuming all methods you want to call have the same signature (you can work around that, if you need a whole bunch of various signatures by using reflection):
// This reflects the signature of the methods you want to call
delegate void theFunction(ActionData data);
class ActionData
{
// put whatever data you would want to pass
// to the functions in this wrapper
}
class Action
{
public Action(theFunction action, ActionData data, bool doIt)
{
this.action = action;
this.data = data;
this.doIt = doIt;
}
public bool doIt
{
get;
set;
}
public ActionData data
{
get;
set;
}
public theFunction action
{
get;
set;
}
public void run()
{
if (doIt)
action(data);
}
}
And a regular use case would look something like this:
class Program
{
static void someMethod(ActionData data)
{
Console.WriteLine("SUP");
}
static void Main(string[] args)
{
Action[] actions = new Action[] {
new Action(Program.someMethod, new ActionData(), true)
};
foreach(Action a in actions)
a.run();
}
}
Yes, you can.
If all your functions share the same signature you might want to store delegates in your collection, otherwise I would go for System.Reflection.MethodInfo, which you can use later on by calling Invoke method. Parameters would be stored as array of objects - that's what Invoke expects.
If using reflection is too slow you can use Reflection.Emit to generate dynamic methods at runtime.
I would just create a List<Action>. Action is a delegate that takes no parameters and returns no results. You can use currying and lambdas such that the actual actions can call a method that has parameters. In the case where you don't actually want to run it, just don't add it to the list in the first place (or add an action that does nothing I guess).
To add an item it might look something like:
list.Add(() => someobject.someMethod(firstArgument, secondArgument));
list.Add(() => anotherObject.anotherMethod(oneArgument));
Then you can just run all of the actions when you want to:
foreach(Action action in list)
{
action();
}
This is exactly what you would use delegates for. Delegates are, more or less, type-checked function pointers. You can create some delegates and put them into an array.
Func<int, int> [] funcs = new Func<int,int>[] { x => 2 * x, x => x * x };
foreach(var fn in funcs)
{
Console.WriteLine(fn(3));
Console.WriteLine(fn(8));
}
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.