47 votes

Est-il possible d'écrire une syntaxe comme - ()() ?

J'ai lu dans un livre électronique (que je cherche désespérément à retrouver) qu'en utilisant les délégués, il est possible d'écrire un code dont la syntaxe est la suivante :

 ()(); // where delegate precedes this.

Quelqu'un peut-il fournir des détails sur la manière dont cela serait possible ou sur la situation dans laquelle cela se produirait ?

127voto

Jon Skeet Points 692016

Vous pouvez faire un peu mieux que les exemples donnés jusqu'à présent, en fait... vous pouvez l'étendre de manière arbitraire :

class Test
{
    delegate Hofstadter Hofstadter();

    static void Main()
    {
        // Unfortunately I'm clearly not as smart as the real thing
        Hofstadter douglas = () => null;

        douglas()()()()()()();
    }
}

Et voici une autre horrible alternative, pour de l'art ASCII supplémentaire :

class Test
{
    delegate __ ___();
    delegate ___ __(___ _);

    static void Main()
    {
        ___ _ = () => null;

        _ ()((_))();
    }
}

S'il vous plaît, ne faites jamais, jamais, jamais cela.

EDIT : Une dernière - bien qu'il s'agisse autant de remplacer les choses par des underscores qu'autre chose, et de réutiliser les noms chaque fois que c'est possible :

class Test
{
    delegate void _();
    delegate __<_> ___<_>();
    delegate ___<_> __<_>(___<_> ____);

    static ___<_> ____<_>(___<_> ____) { return ____; }
    static __<_> ____<_>() { return ____<_>; }

    static void Main()
    {
        ((__<_>)____)(____<_>)();
    }
}

35voto

Reed Copsey Points 315315

Voici un exemple de programme qui en fait la démonstration :

using System;

class Program
{
    static Action GetMethod()
    {
        return () => Console.WriteLine("Executing");
    }
    static void Main()
    {
        GetMethod()();
        Console.ReadKey();
    }
}

Cela dit, je ne ferais jamais cela dans un code de production. C'est très inattendu.


Edit : Juste au cas où vous voudriez voir quelque chose d'encore plus laid... [surtout le " ()()[()=>{}]() "] :

using System;

class Program
{
    static void Main()
    {
        (new Program()).Confusion();
        Console.ReadKey();
    }

    public Action this[Action index]
    {
        get {
            return () => Console.WriteLine("Executing");
        }
    }

    Func<Program> GetInstance()
    {
        return () => this;
    }

    void Confusion()
    {
        // This is particularly ugly...
        GetInstance()()[()=>{}]();
    }
}

12voto

Richard Points 54016

Il suffit d'un peu d'autoréférencement, et vous pouvez l'appeler autant de fois que vous le souhaitez :

delegate Foo Foo();

class Program {
    static void Main(string[] args) {
        Foo f = null;
        f = () => f;
        // Add more "()" as you feel like...
        f()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()();
    }
}

9voto

dtb Points 104373
static void Foo()
{
    Console.WriteLine("Hello World!");
}

static Action Bar()
{
    return new Action(Foo);
}

static void Main()
{
    Func<Action> func = new Func<Action>(Bar);
    func()();

    Bar()();
}

empreintes

Hello World!
Hello World!

Cela fonctionne, car func() et Bar() renvoie un Action qui peut être invoqué à l'aide de la syntaxe normale d'invocation des méthodes.

2voto

csharptest.net Points 16556

Quelque chose comme :

delegate void FunctionA();
delegate FunctionA FunctionB();

void TestA() { }
FunctionA TestB() { return TestA; }

void Main()
{
   TestB()();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X