Best (General) Func Delegate Declaration

ok, I hope the title of this question makes sense. In my application, I have some methods that should be called by a special InvokeMethod. Currently it works as follows:

internal bool RemoteLogin(string password) { return (bool)InvokeMethod(new Func<string, bool>(Server.RemoteLogin), password); } internal string GetSessionId() { return (string)InvokeMethod(new Func<string>(Server.GetSessionId)); } public object InvokeMethod(Delegate method, params object[] args) { return method.DynamicInvoke(args); } 

To call InvokeMethod, I have to pass the new Func <....>, add the parameter (s), and also return the return value to the appropriate type. Is there a better (more general) way to do this, for example, using Generics or Reflection?

Any help is appreciated.

+4
source share
5 answers

You can achieve a certain amount of strong input - by repeating with Func options:

 public R InvokeMethod<T,R>(Func<T,R> method, T argument) { return method(argument); } public R InvokeMethod<T1,T2,R>(Func<T1,T2,R> method, T1 argument1, T2 argument2) { return method(argument1, argument2); } public R InvokeMethod<T1,T2,T3,R>(Func<T1,T2,T3,R> method, T1 argument1, T2 argument2, T3 argument3) { return method(argument1, argument2, argument3); } 

And so on.

Although this is consistent with your original, there is no real need to handle the parameters at all. Try writing InvokeMethod as follows:

 public R InvokeMethod<R>(Func<R> method) { return method(); } 

and then call it in this style:

 internal bool RemoteLogin(string password) { return InvokeMethod(() => Server.RemoteLogin(password)); } internal string GetSessionId() { return InvokeMethod( () => Server.GetSessionId()); } 

That way you leave parameter processing with the lambda expression, and you only need to write InvokeMethod once.

+3
source

"In my example above, the InvokeMethod method is simplified. In my application, it performs logging, monitoring, exception handling, etc. of the call."

Given this comment, my suggestion is to redo this. Instead of calling a delegate like this, you can do a Func<T> operation, for example:

 public T InvokeMethod<T>(Func<T> method) { // Add wrapper as needed return method(); } 

Then you can call it using lambdas when you need to pass parameters:

 internal bool RemoteLogin(string password) { return InvokeMethod(() => Server.RemoteLogin(password)); } internal string GetSessionId() { return InvokeMethod(Server.GetSessionId); } 
+2
source

I agree with Reed that you can really just call the method directly and eliminate some redundant code, but if you want strong typing when you do these things, it is very easy to rewrite InvokeMethod call InvokeMethod this.

 public static T InvokeMethod<T>(Delegate method, params object[] args) { return (T)method.DynamicInvoke(args); } 

Then your call above just becomes:

 return InvokeMethod(new Func<string, bool>(Server.RemoteLogin), password); 

And the return type of Boolean is inferred using the return type in your method.

+1
source
 static T Invoke<T>(Func<T> method) { //Log here return method(); } bool RemoteLogin(string password) { return Invoke(() => Server.RemoteLogin(password)); } 
+1
source

Additional information: If the method does not have a return value (for example, "void Logout ()"), you can use the Action delegate (the method may have name-name → InvokeMethod → ​​due to a different signature / parameter):

 public void InvokeMethod(Action method) { method(); } 
+1
source

Source: https://habr.com/ru/post/1397924/


All Articles