Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中从PHP执行这3个操作(主要是自省)_C#_Php_Oop - Fatal编程技术网

如何在C#中从PHP执行这3个操作(主要是自省)

如何在C#中从PHP执行这3个操作(主要是自省),c#,php,oop,C#,Php,Oop,第一个问题: 在PHP中有: $b = new SomeClass(); $a = "foo"; $b->$a("something"); // This is the same as $b->foo("something"); 在C#中你是如何做到这一点的 第二个问题: 在PHP中,我可以迭代类上的每个方法,类似于: $a = new SomeClass(); // Which implements methodA, methodB; foreach($method in ge

第一个问题:

在PHP中有:

$b = new SomeClass();
$a = "foo";
$b->$a("something"); // This is the same as $b->foo("something");
在C#中你是如何做到这一点的


第二个问题:

在PHP中,我可以迭代类上的每个方法,类似于:

$a = new SomeClass(); // Which implements methodA, methodB;
foreach($method in get_class_methods(SomeClass()))
{
  $method("do stuff with each method");
}
如何在C#中执行此操作


第三项问题

PHP有一个神奇的方法
\u call()
,如果一个类没有实现一个方法,它会将其作为默认值执行,比如如果一个方法不存在,它仍然可以运行

class NewClass()
{
// constructor

__call(class name, array of parameters)
{

}
}
所以如果你这样做了

$a = new NewClass();
$a->thisDoesntExistButWorks("123","abc");

// The method gets "magically created"  such as
thisDoesntExistButWorks(array with 123 and abc)....
  • 是我能想到的最接近的事情()

  • 您可以使用()

  • 您可以创建一个。在PHP中,除非定义它的功能,否则它不是很有用

  • 也就是说,我会避免做这样的事情(即使是在PHP中)

  • 是我能想到的最接近的事情()

  • 您可以使用()

  • 您可以创建一个。在PHP中,除非定义它的功能,否则它不是很有用


  • 也就是说,我会避免做这样的事情(即使是在PHP中)

    在C#中没有一个PHP功能可以如此优雅地实现,但除了第三个功能之外,它们都是可以实现的

    1:

    2:

    您可以在3.5中实现一个扩展方法ForEach()(可能在4.0的Linq库中提供),将其转化为方法链;大括号中的代码将成为lambda


    好吧,在C语言中,任何内置方式都不可能实现3。您可以通过尝试在try块中反射地调用该方法来解决这个问题,捕获调用失败时抛出的任何targetException,并在catch中实现您的默认行为。

    您的PHP功能在C#中都无法如此优雅地实现,但除了第三个之外,它们都是可能的

    1:

    2:

    您可以在3.5中实现一个扩展方法ForEach()(可能在4.0的Linq库中提供),将其转化为方法链;大括号中的代码将成为lambda


    好吧,在C语言中,任何内置方式都不可能实现3。您可以通过尝试在try块中反射调用该方法,捕获调用失败时抛出的任何targetException,并在catch中实现默认行为来解决此问题。

    以下是一些基于反射的动态调用方法的资源:


    以下是一些基于反射的资源,用于动态调用方法:

    第一

    var method_name = "my_method"
    // you can change the null by the parameters you need
    my_object.GetType().GetMethod(method_name).Invoke(my_object, null);
    

    第二


    第三

    我不知道怎样才能在C#中做类似的事情,但如果你告诉我你的问题,肯定会有解决办法的。

    1

    var method_name = "my_method"
    // you can change the null by the parameters you need
    my_object.GetType().GetMethod(method_name).Invoke(my_object, null);
    

    第二


    第三


    我不知道你怎样才能在C#中做到这一点,但如果你说出你的问题,肯定会有解决办法。

    1和2已经被回答了不止一次。所以我将尝试3

    C#不提供未知方法,因为它不必提供未知方法。如果像
    a.NonExistentMethod()
    那样直接调用该方法,那么程序就不会编译,在运行时捕获错误调用的想法也无关紧要

    正如您已经发现的,通过执行
    a.GetType().GetMethod(“NoneExistentMethod”).Invoke(a,新对象[0])
    ,可以在运行时动态调用方法。这将因
    NullReferenceException
    而失败,因为对
    GetMethod
    的调用返回null。然而,这种情况是可以检测到的,所以也许我们可以对此采取一些措施。下面是一个扩展方法,其行为尽可能类似于PHP。请注意,这是未经测试的,不应在生产(甚至可能是实验)代码中使用

    这可以通过执行以下操作来使用
    a.CallOrDefault(“方法名称”,arg1,arg2)

    公共静态类PhpStyleDynamicMethod
    {
    公共静态void\uu调用(类型@class,对象[]参数)
    {
    //在这里做事。
    }
    公共静态对象CallOrDefault(此对象b,字符串方法,params对象[]参数)
    {
    var methods=b.GetType().GetMethods()。其中(m=>m.Name==method&&DoParametersMatch(m.GetParameters(),parameters));
    var count=methods.count();
    如果(计数=1)
    返回方法.Single().Invoke(b,参数);
    如果(计数>1)
    抛出新的ApplicationException(“无法解析单个方法”);
    __调用(b.GetType(),参数);
    返回null;
    }
    公共静态bool DoParametersMatch(ParameterInfo[]参数,对象[]值)
    {
    if(parameters==null&&values==null)返回true;
    if(parameters==null)返回false;
    if(value==null)返回false;
    if(parameters.Length!=values.Length)返回false;
    对于(int i=0;i
    1和2已被回答多次。所以我将尝试3

    C#不提供未知方法,因为它不必提供未知方法。如果像
    a.NonExistentMethod()
    那样直接调用该方法,那么程序就不会编译,在运行时捕获错误调用的想法也无关紧要

    正如您已经发现的,通过执行
    a.GetType().GetMethod(“NoneExistentMethod”).Invoke(a,新对象[0])
    ,可以在运行时动态调用方法。这将因
    NullReferenceException
    而失败,因为对
    GetMethod
    的调用返回null。然而,这种情况是可以检测到的,所以也许我们可以对此采取一些措施。下面是一个扩展方法,其行为尽可能类似于PHP。请注意,这是未经测试的,不应在生产(甚至可能是实验)代码中使用

    这可以通过执行以下操作来使用
    var method_name = "my_method"
    // you can change the null by the parameters you need
    my_object.GetType().GetMethod(method_name).Invoke(my_object, null);
    
    MethodInfo[] methodInfos = typeof(MyClass).GetMethods();
    
    foreach (MethodInfo methodInfo in methodInfos)
    {
        /* doing stuff... */
    }
    
    public static class PhpStyleDynamicMethod
    {
        public static void __call(Type @class, object[] parameters)
        {
            // Do stuff here.
        }
    
        public static object CallOrDefault(this object b, string method, params object[] parameters)
        {
            var methods = b.GetType().GetMethods().Where(m => m.Name == method && DoParametersMatch(m.GetParameters(), parameters));
    
            var count = methods.Count();
    
            if (count == 1)
                return methods.Single().Invoke(b, parameters);
    
            if (count > 1)
                throw new ApplicationException("could not resolve a single method.");
    
            __call(b.GetType(), parameters);
    
            return null;
        }
    
        public static bool DoParametersMatch(ParameterInfo[] parameters, object[] values)
        {
            if (parameters == null && values == null) return true;
            if (parameters == null) return false;
            if (values == null) return false;
            if (parameters.Length != values.Length) return false;
    
            for(int i = 0; i < parameters.Length; i++)
            {
                var parameter = parameters[i];
                var value = values[i];
    
                if (!parameter.GetType().IsAssignableFrom(value.GetType()))
                    return false;
            }
    
            return true;
        }
    }