Hook to function without delegates (Reflection) - c#

Is there a way I could use reflection to hook one function to another without using delegates?
class A
{
void Foo()
{
}
}
class B
{
void Main()
{
A a = new A();
a.GetType().GetMethod("Foo").AddHook(a, Func); //I want something like this
a.Foo();
//Func gets called
}
void Func()
{
}
}
Is there a way to call Func after Foo was called without using events, delegates or just calling Func from inside Foo?
I need this so my game's UI controller can get updated.
The way I see most people dealing with this is by adding a bunch of events to A and subscribing B to those. Like this
class A
{
‎ public delegate void UICallback();
‎ public event UICallback onFoo;
void Foo()
{
‎ onFoo.Invoke();
}
}
class B
{
void Main()
{
A a = new A();
‎a.onFoo += Func;
a.Foo();
}
void Func()
{
}
}
The problem I find with this approach is that I'd need to add a bunch of events like these (probably more than 5 or even 10) to many classes and then remember to invoke those at the end of a function to update UI (invoke onBattleStarted at the end of StartBattle(), for example). This, in addition to increasing the size of my classes with big blocks of event declarations making it ugly to read, makes it a harder maintain.
EDIT I think no one really understands what I'm looking for... I'd like a way to hook Func to Foo without making any changes to Foo, i.e. without Foo knowing this callback exists. Using an action won't help since I'd need specify on Foo's parameters that it should call Func
Thank you for your help!

You Can call Action at the end of Func().
Class A
{
void Foo()
{
}
}
Class B
{
void Main()
{
A a = new A();
Func( () => {a.Foo();});
}
void Func(Action onFinish)
{
//Enter your code here
onFinish();
}

There is the method chaining pattern if that can solve your problem:
namespace Assets
{
public class Example
{
public Example GrabSomeFoodInTheFridge()
{
// some work
return this;
}
public Example WatchTv()
{
// some work
return this;
}
public Example EatFood()
{
// some work
return this;
}
}
public class Demo
{
public Demo()
{
var example = new Example();
var instance = example
.GrabSomeFoodInTheFridge()
.EatFood()
.WatchTv();
}
}
}
It does not use reflection at all, additionally you could leverage interfaces and extension methods.

Related

Custom class working like a using statement with curly braces

Is it possible to create a class, or operator, that would work like using does?
Example:
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
count++;
}
}
Often we use the using statement to not have to handle post operations manually, like dispose and such.
I have in mind a couple of usage of this mechanic.
But I cannot figure out how to achieve this.
An example of actual implementation:
MyClass mc = new MyClass();
MyClass sub = mc.GoDown();
//Do things on sub
sub.GoUp();
What I would like it to be:
MyClass mc = new MyClass();
mc.GoDown {
//Do things on sub
} // GoUp
I know I could use a try {} finally {}.
I am just curious if there is a way to do what using is doing.
Edit:
I do know about the IDispose implementation.
I am just wondering if we can do what using does without using.
Edit #2:
Improved the example.
Your class simply needs to implement IDisposable to support usage in a using block:
public class MyClass : IDisposable
{
public void Dispose()
{
// Do your cleanup
}
}
Then you can use:
using (var instance = new MyClass())
{
}
Do read Implementing a Dispose method on Microsoft Docs though.
Here's how you'd make the example work by passing in an Action<MyClass> to GoDown and GoDown will handle calling GoUp on sub.
public class MyClass
{
public MyClass GoDown(Action<MyClass> doStuff)
{
var sub = new MyClass();
//Whatever GoDown did to create a MyClass goes here
try
{
doStuff(sub);
}
finally
{
sub.GoUp();
}
}
}
Then call it like this.
MyClass mc = new MyClass();
mc.GoDown(sub =>
{
//Do things on sub
});
And GoUp will be called on sub even if there's an exception in the delegate you pass in.
The closest construct to what you suggested I can think of would be a method that takes an object and Func or Action as an argument and if the object is of certain type - e.g. implements an interface, then performs the task.
Let's start with an interface:
public interface IMyWrapper
{
void Do();
}
For simplicity I created a single example for an Action that does not take any arguments:
public class MyWrapper
{
public static void MyWrapperMethod(IMyWrapper wrapped, Action doStuff)
{
try
{
doStuff();
}
finally
{
wrapped.Do();
}
}
public static void MyWrapperMethod(object notWrapped, Action doStuff)
{
doStuff();
}
}
IF you pass an object that implements IMyWrapper interface it will run the Do() method of the IMyWrapper interface, after performing what's in the doStuff action. Else it will just run the doStuff.
To invoke that run it like that:
MyWrapper.MyWrapperMethod(new object(), () =>
{
Console.WriteLine("Do stuff");
});
This will only write "Do stuff".
Let's now create a class that impments the interface:
public class MyWrappedClass : IMyWrapper
{
public void Do()
{
Console.WriteLine("I implement the wrapper.");
}
}
and use it in the MyWrapperMethod:
var myWrappedClass = new MyWrappedClass();
MyWrapper.MyWrapperMethod(myWrappedClass, () =>
{
Console.WriteLine("Do stuff");
});
This will print "Do stuff" and "I implement the wrapper". This is b/c the MyWrapperMethod will execute the Do method for us.
That's the closest to what using does I could think of.

Exchange implementations for C# methods

Is it possible to exchange implementations of methods in C#, like method swizzling in Objective-C?
So I could replace an existing implementation (from an outside source, via a dll for example) at runtime with my own (or add another onto it).
I have searched for this, but have found nothing of value.
You could use delegates to have your code point to whatever method you wish to execute at run time.
public delegate void SampleDelegate(string input);
The above is a function pointer to any method which yields void and takes a string as input. You can assign any method to it which has that signature. This can also be done at run time.
A simple tutorial can be also found on MSDN.
EDIT, as per your comment:
public delegate void SampleDelegate(string input);
...
//Method 1
public void InputStringToDB(string input)
{
//Input the string to DB
}
...
//Method 2
public void UploadStringToWeb(string input)
{
//Upload the string to the web.
}
...
//Delegate caller
public void DoSomething(string param1, string param2, SampleDelegate uploadFunction)
{
...
uploadFunction("some string");
}
...
//Method selection: (assumes that this is in the same class as Method1 and Method2.
if(inputToDb)
DoSomething("param1", "param2", this.InputStringToDB);
else
DoSomething("param1", "param2", this.UploadStringToWeb);
You can also use Lambda Expressions: DoSomething("param1", "param2", (str) => {// what ever you need to do here });
Another alternative would be to use the Strategy Design Pattern. In this case, you declare interfaces and use them to denote the behavior provided.
public interface IPrintable
{
public void Print();
}
public class PrintToConsole : IPrintable
{
public void Print()
{
//Print to console
}
}
public class PrintToPrinter : IPrintable
{
public void Print()
{
//Print to printer
}
}
public void DoSomething(IPrintable printer)
{
...
printer.Print();
}
...
if(printToConsole)
DoSomething(new PrintToConsole());
else
DoSomething(new PrintToPrinter());
The second approach is slightly more rigid than the first, but I think it is also another way to go around achieving what you want.
The only way to "replace methods" is to use delegates.
If your code looks like this:
public void Foo()
{
Bar();
}
public void Bar()
{
}
Then you cannot get Foo to call any other method than Bar. The method dispatch table you refer to in Objective-C is not mutable in .NET.
To be able to specify which method Foo should call above you need to use a delegate:
public void Foo(Action whichMethod)
{
whichMethod();
}
And you could call it like this:
Foo(Bar);
Foo(Baz);
But the method has to be built to allow this kind of runtime replacement.
While this isn't the best path to object-oriented programming in a strongly-typed language, it's worth to mention that since .NET 4.0, C# has included the Dynamic Language Runtime (DLR) which allows dynamic programming. One of most curious dynamic objects is ExpandoObject: a fully runtime-expandable object:
dynamic expando = new ExpandoObject();
expando.DoStuff = new Func<string>(() => "hello world");
// Now you can swap DoStuff with other method setting another delegate:
expando.DoStuff = new Func<string, string>(text => text + "!");
BTW, as I said above, I've shared this approach here just for learning purposes. It might be useful in some edge cases, but as C# is a compiled and strongly-typed language, you should avoid this approach in 99.99% of cases.
void Test(Action method) {
if ( method != null ) method.invoke();
}
you can call this
Test( () => { Console.WriteLine("hello world"); } )
change def and call again
Test( () => { MessageBox.Show("Hi"); } )

C# solving pseudocode to help understanding delegates&lambda

I have trouble understanding lambdas, delegates and so on, I hope with someone giving me a solution to my problem I am able to understand those better. Basically it is possible to create (or change) the body of a method when an object of the class is initialized, no?
Kinda like this:
Let's say I have 1 classes: Class A, which looks like this:
public class ClassA{
int i;
public ClassA(int number)
{
i = number;
}
public void Foo(){}
}
For demonstration purposes very minimalistic, now I also have somewhere else the static main, and what I want to do there is following: Creating multiple objects of ClassA and make it so that when I call ClassA.Foo I get different results I can determine myself, how is it supposed to look Syntax wise?
static void Main(string[] args)
{
ClassA FooBlue = New ClassA(1){
public void Foo()
{
System.Console.WriteLine("I am a Fooranger Blue!");
};
ClassA FooPink = New ClassA(2){
public void Foo()
{
System.Console.WriteLine("My color is the manliest!");
};
...
So now when I do this:
...
FooBlue.Foo();
FooPink.Foo();
System.Console.ReadLine();
}
I get following output on the console:
"I am a Fooranger Blue!"
"My color is the manliest!"
I just mention again that this is an example and by no means anything out of praxis but for the purpose of me understanding that stuff it would be great if someone can provide an answer that gives the desired solution, including the useless integer i.
To accomplish the goal of "providing the implementation of a method when constructing the type" you can indeed use delegates. Simply accept a delegate when constructing the object and invoke it when you want it to be executed:
public class ClassA
{
private Action action;
public ClassA(Action action)
{
this.action = action;
}
public void Foo()
{
action();
}
}
The syntax for a lambda is different than the syntax for creating a named method from a class' definition:
var fooBlue = new ClassA(() => Console.WriteLine("I am a Fooranger Blue!"));

Make methods work independently without using a common method

I am currently trying to separate out the method implementation so that they can work independently. The methods that I am trying to separate are store and checker. Both these methods require the traverse method. My current implementation has two method store and checker methods which I have separated them into different classes. They require to be called within the traverse method to work. This is the my current implementation.
class Traverse
{
public void traversemethod()
{
Console.WriteLine("Traverse function");
Checker r = new Checker();
r.checkermethod();
Store s = new Store();
s.storemethod();
}
}
class Checker
{
public void checkermethod()
{
Console.WriteLine("Checker function");
}
}
class Store
{
public void storemethod()
{
Console.WriteLine("Store function");
}
}
class Compute
{
public static void Main()
{
Console.WriteLine("Main function");
Traverse v = new Traverse();
v.traversemethod();
Console.ReadLine();
}
Is there any way by which I can implement them separately without declaring them together in traverse method and calling both store and checker method separately in the main function. I can implement the traverse method in both store and checker method, but i was wondering if there is any way to do it rather than duplicating the same code again.
Sounds like a perfect place to use a lambda:
public delegate void TraverseDelegate();
public void traversemethod(TraverseDelegate dlg){
Console.WriteLine("Traverse function");
dlg();
}
and in the Main method use:
Traverse v = new Traverse();
v.traversemethod(() => {
Checker r = new Checker();
r.checkermethod();
Store s = new Store();
s.storemethod();
});
EDIT/UPDATE(=UPDIT :-) )
You can also make the delegate a member field of Traverse, and then pass it as a constructor argument and call traversemethod without any arguments:
public class Traverse{
public delegate void TraverseDelegate();
private TraverseDelegate dlg;
public Traverse(TraverseDelegate dlg){
this.dlg=dlg;
}
public void traversemethod(){
Console.WriteLine("Traverse function");
dlg();
}
}
and in the Main method use:
Traverse v=new Traverse(()=>{
Checker r = new Checker();
r.checkermethod();
Store s = new Store();
s.storemethod();
});
v.traversemethod();
I'm not about the relationship between Checker and Store so I'll show an example with an interface instead of a base class. However you could create a base class, possibly abstract, and have each child class implement their special method.
interface IPerformMethod
{
void SpecialFunction();
}
public class Store : IPerformMethod
{
public void SpecialFunction()
{
Console.WriteLine("Store function");
}
}
public class Checker : IPerformMethod
{
public void SpecialFunction()
{
Console.WriteLine("Checker function");
}
}
Then in your TraverseMethod, you could pass in an object that implements IPerformMethod (in this case it's either an instance of Checker or Store).
public void TraverseMethod(IPerformMethod item)
{
Console.WriteLine("Traverse function");
item.SpecialFunction();
}
//To call the method
TraverseMethod(new Checker());
TraverseMethod(new Store());
(Obviously you can rename the IPerformMethod interface to something more descriptive but if I understand the question correctly, this seems to be what you want).

Method or Extension Method to Handle InvokeRequired

I can't quite come up with the solution to creating a generic method to handle the InvokeRequired for void methods (I'll deal with return values later). I was thinking something like:
// Probably not the best name, any ideas? :)
public static void CheckInvoke(this Control instance,
,Action<object, object> action)
{
if (instance.InvokeRequired)
{
instance.Invoke(new MethodInvoker(() => action));
}
else
{
action()
}
}
Then I could write something like:
public partial class MyForm : Form
{
private ThreadedClass c = new ThreadedClass();
public MyForm()
{
c.ThreadedEvent += this.CheckInvoke(this
,this.MethodRequiresInvoke
,sender
,e);
}
}
This doesn't compile obviously, I just can't quite tie it together.
Hans is correct, in that you probably don't want to wrap code like this up, especially since it can cause some debugging issues down the road in determining what thread actions are happening on. That said, this would be the signature you'd want:
public static class FormsExt
{
public static void UnwiseInvoke(this Control instance, Action toDo)
{
if(instance.InvokeRequired)
{
instance.Invoke(toDo);
}
else
{
toDo();
}
}
}
Loose Action parameters of "object,object" (as JerKimball suggests), name it SafeInvoke, and attach to event via anonymous delegate:
c.ThreadedEvent += delegate
{
c.SafeInvoke(this.MethodRequiresInvoke);
};

Categories