C#中的函数用于调用php中的类/方法

时间:2012-10-22 03:03:45

标签: c# asp.net

我迈出了第一步c#& asp.net,我很享受。 现在,我有一个问题...... 在C#中有一个函数来调用php中的类/方法吗? 例如:

$class = array(
    "foo", // class name
    "bar" // method name
);
$params = array(
    "one",
    "two"
);
call_user_func_array($class, $params); //execute Foo->bar("one","two");

3 个答案:

答案 0 :(得分:3)

不,没有内置的东西可以做到这一点。您可以构建一个使用反射执行类似操作的方法,但它似乎是一个寻找问题的解决方案。

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);
}

答案 1 :(得分:2)

正如其他人所说,有多种方法可以模拟这种情况,但C#中没有“烘焙”功能。最灵活的方法是使用反射,但是如果你知道事先要调用的方法列表,你可以用更简单(也更容易处理)的方式来实现。

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, does work.

如果您知道您希望以这种方式提供哪种方法,我建议您重新考虑一下您正在尝试做什么。我可以考虑使用字符串来选择执行路径的唯一原因是,如果您计划从用户那里获取这些字符串。如此暴露应用程序的内部细节不仅是一个巨大的禁忌,而且危险地接近eval类型的功能。 C#没有eval方法是有原因的,并不是因为设计师忘了把它放进去。

答案 2 :(得分:1)

正如@StriplingWarrior所说,没有内置的等效call_user_func_array,但你可以用反射做类似的事情。

问题在于,反射代码可以非常快速地变得非常复杂,并且如果你不是非常小心的话,它可能很脆弱且容易出错。

例如,以下功能可以满足您的需求:

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);
}

你这样称呼它:

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

CallUserFuncArray(func, args);

问题很多。

  • 仅当Bar是公共静态方法时,代码才有效。
  • 如果需要在对象上调用实例方法,则会出现一个全新的复杂层。
  • 如果args数组中的参数不适合目标方法,代码将会爆炸。
  • 这里没有支持调用除字符串参数之外的任何东西的方法。可以在调用'Invoke'之前查询方法所期望的参数类型并转换类型,但是你会变得更加混乱。
  • 如果你需要满足它们的需要,还有更多的边缘情况会使这个代码的复杂性更加突出。

用卡尔·富兰克林(dotNetRocks成名)来解释:

  

我遇到了需要解决的问题,所以我使用了Reflection。现在我有两个问题。

我发现你需要做这类事情,然后你可能需要重新思考你的整体设计。