Is there a C # functionality similar to PHP __call?

6

I have a lot of experience with PHP, and as I'm starting with C # now, it's going to be common for me to want to compare one language with another to find out if I can do something similar.

In PHP, I can add a functionality to a class so that, when the method does not exist, an action is performed. This is the magic __call method. That is, it adds a dynamic call to methods that have not been defined in the class based on what is set to __call .

According to the Manual:

  

__ call () is triggered when invoking inaccessible methods in an object context.

For example,

 class Dynamic {

        public function action() {
           return 'existe';
        }

        public function __call($method, $parameters) {
              return "Não existe, mas farei alguma coisa com {$method}";
        }
 }


 $d = new Dynamic();

 $d->action(); // 'existe'

 $d->naoExisteEsseMetodo(); // 'Não existe, mas farei alguma coisa com naoExisteEsseMethodo'

Note that the last named method does not exist, but "something is done" anyway.

Is there any way to create functionality similar to the __call of PHP in C #?

    
asked by anonymous 28.06.2016 / 16:18

4 answers

8

You are looking for class DynamicObject

28.06.2016 / 17:22
8

Do not try to compare C # with PHP!

I do not say this out of spite, but because they are different languages with their particularities. C # is extremely typed, that is, it is not possible to do something of that level naturally. However, in version 4.0 of C #, the dynamic type was introduced, where you can do something " similar. "

static void Main(string[] args)
{
    ExampleClass ec = new ExampleClass();

    dynamic dynamic_ec = new ExampleClass();

    dynamic_ec.exampleMethod1(10, 4);
     // As seguintes chamadas não causam erros do compilador, se 
    // existe ou não métodos apropriados. 
    dynamic_ec.someMethod("some argument", 7, null);
    dynamic_ec.nonexistentMethod();
}

class ExampleClass
{
    public ExampleClass() { }
    public ExampleClass(int v) { }

    public void exampleMethod1(int i) { }

    public void exampleMethod2(string str) { }
}

Another way is also to use reflections, as spoken in the @jbueno response. , something like this:

ExampleClass ec = new ExampleClass();
Type type = ec .GetType();
MethodInfo m = type.GetMethod("nonexistentMethod");
m.Invoke(ec , new object[] {});

However, it's worth noting that I does not see a need to use something like this, not in the context of the question.

References:

28.06.2016 / 16:32
6

As far as I know, it does not exist. For the simple fact that C # is completely different from PHP.

If you try to call a method that does not exist in C #, the application will not compile and ready. No strategy is required if you try to call a method that does not exist. Of course you can "try" to call a method that does not exist using reflection , there you need to implement some strategy to execute something when the method does not exist.

Example, if you try something like obj.GetType().GetMethod("MetodoInexistente").Invoke(a, new object[0]) you will get a NullReferenceException .

See this answer in StackOverflow, for a question similar to yours. In this case, obj.CallOrDefault("MetodoInexistente", arg1, arg2);

public static class PhpStyleDynamicMethod
{
    public static void __call(Type @class, object[] parameters)
    {
        // Aqui vai a implementação do "__call"
    }

    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;
    }
}
    
28.06.2016 / 16:21
0

Well ... one of the basic differences between C # and PHP is that C # is a TIPADA language, ie the types are known with their characteristics (methods and properties), since PHP is an untyped language, so has a generic method that when called something that does not exist this is invoked.

The good part about being typed is that it helps the development tool a lot to help you, since intellisense (a command prompt when you start typing) can already predict what that object has, including extended methods. which one you can create and extend a method for a system class!

So ... I do not see why C # has anything like "_CALL" since it will use the project will know all available features, even if it is a DLL referenced to your project.

Welcome to the .NET world!

    
21.07.2016 / 22:36