Function in C # to call class / method like in php

I am taking the first steps in C # and asp.net, and I really like it. Now I have a question ... Is there a function in C # to call a class / method, like in php?
For instance:

$class = array( "foo", // class name "bar" // method name ); $params = array( "one", "two" ); call_user_func_array($class, $params); //execute Foo->bar("one","two"); 
+4
source share
3 answers

No, there is nothing that could be done. You can create a method that does something like this with reflection, but it seems like a solution looking for a problem.

 void Main() { CallUserFuncArray("UserQuery+Foo", "Bar", "One", "Two"); } // Define other methods and classes here public class Foo { public static void Bar(string a, string b){} } public void CallUserFuncArray(string className, string methodName, params object[] args) { Type.GetType(className).GetMethod(methodName).Invoke(null, args); } 
+3
source

As others have noted, there are several ways to simulate this, but there are no “baked” features in C #. The most flexible way is with reflection, but you can make it much easier (and easier to deal with) if you know the list of methods that you will name in advance.

 class Foo { public static string FooA(int p1, int p2) { return "FooA:" + p1 + p2; } public static string FooB(int p1, int p2) { return "FooB:" + p1 + p2; } public static string FooC(int p1, int p2) { return "FooC:" + p1 + p2; } } class Bar { //You can use Func<int, int, object> instead of a delegate type, //but this way is a little easier to read. public delegate string Del(int p1, int p2); public static string DoStuff() { var classes = new Dictionary<string, Dictionary<string, Del>>(); classes.Add("Foo", new Dictionary<string, Del>()); classes["Foo"].Add("FooA", Foo.FooA); classes["Foo"].Add("FooB", Foo.FooB); classes["Foo"].Add("FooC", Foo.FooC); //...snip... return classes["Foo"]["FooA"](5, 7); } } 

Which, by the way, works.

If you do not know what methods you want to make available in this way, I suggest that you review everything that you are trying to do. The only reason I can think of using strings to select the execution path will be if you plan to get these strings from the user. Not only does the sheer amount of no-no reveal the internal details of your application like this, but it is dangerously close to the eval -type functionality. There is a reason why C # does not have an eval method, and not because designers forgot to insert it.

+2
source

As @StriplingWarrior said, there is no built-in equivalent to call_user_func_array , but you can do something like Reflection.

The problem is that Reflection code can get very complicated quickly and can be fragile and error prone if you are NOT VERY careful.

For example, the following function does what you want:

 public static void CallUserFuncArray(string[] func, params string[] args) { var type = Type.GetType(func[0]); if (type == null) { throw new ArgumentException("The specified Class could not be found"); } var method = type.GetMethod(func[1], BindingFlags.Static | BindingFlags.Public); if (method== null) { throw new ArgumentException("The specified Method could not be found"); } method.Invoke(null, args); } 

You call it like this:

 var func = new [] { "Foo", "Bar" }; var args = new [] { "one", "two" }; CallUserFuncArray(func, args); 

However, there are many problems.

  • The code only works if Bar is a public static method.
  • If you need to call an instance method on an object, you will need a new level of complexity.
  • The code will explode if the parameters in the args array args not suitable for the target method.
  • There is no support for calling methods that expect nothing but string parameters. It is possible to query the type of arguments expected by the method and convert the types before invoking Invoke, but you get even messier.
  • There are many more edge cases that further complicate the complexity of this code if you need to service them.

To paraphrase Carl Franklin (from the glory of dotNetRocks):

I had a problem that I needed to solve, so I used Reflection. Now I have two problems.

I believe that you need to do such things, then you will probably have to rethink your overall design.

+1
source

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


All Articles