c# property - C # -Methodenattribut kann keinen Lambda-Ausdruck enthalten?





expression bodied (2)


Ja das ist korrekt. Attributwerte sind auf Konstanten der folgenden Typen beschränkt

  • Einfache Typen (bool, byte, char, short, int, long, float und double)
  • Zeichenfolge
  • Systemtyp
  • enums
  • Objekt (Das Argument für einen Attributparameter des Typs Objekt muss ein konstanter Wert eines der oben genannten Typen sein.)
  • Eindimensionale Arrays der oben genannten Typen

Referenz: http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx

IntelliSense sagt mir "Expression kann keine anonymen Methoden oder Lambda-Ausdrücke enthalten." "Ja wirklich?" Ich war mir dieser auferlegten Einschränkung nicht bewusst. Ist das richtig? Ich denke, ich suche hier einen Plausibilitätscheck ...


public delegate bool Bar(string s);

[AttributeUsage(AttributeTargets.All)]
public class Foo : Attribute
{
    public readonly Bar bar;

    public Foo(Bar bar)
    {
        this.bar = bar;
    }
}

public class Usage
{
    [Foo(b => b == "Hello World!")]        // IntelliSense Complains here
    public Usage()
    {
    }
}



Dieser Fehler wurde bereits im JDK-Bug-System gemeldet: https://bugs.openjdk.java.net/browse/JDK-8029718 . Wie Sie überprüfen können, wurde der Fehler behoben. Dieser Fix synchronisiert Javac mit der Spezifikation in diesem Aspekt. Gerade jetzt akzeptiert javac die Version mit impliziten lambdas korrekt. Um dieses Update zu erhalten, müssen Sie javac 8 repo klonen.

Die Lösung besteht darin, den Lambda-Körper zu analysieren und festzustellen, ob er leer oder wertkompatibel ist. Um dies zu ermitteln, müssen Sie alle Rückgabeanweisungen analysieren. Erinnern wir uns an die Spezifikation (15.27.2), auf die bereits oben verwiesen wurde:

  • Ein Block-Lambda-Textkörper ist voidkompatibel, wenn jede return-Anweisung im Block die Form return hat.
  • Ein Block-Lambda-Text ist wertkompatibel, wenn er nicht normal beendet werden kann ( 14.21 ) und jede return-Anweisung im Block die Form return Expression hat.

Dies bedeutet, dass Sie durch die Analyse der Rückgabewerte im Lambda-Körper wissen können, ob der Lambda-Körper voidkompatibel ist, aber um festzustellen, ob der Wert kompatibel ist, müssen Sie auch eine Flussanalyse durchführen, um festzustellen, ob er normal ausgeführt werden kann ( 14.21 ).

Dieser Fix führt auch einen neuen Compilerfehler für Fälle ein, in denen der Body weder leer noch wertkompatibel ist, beispielsweise wenn wir diesen Code kompilieren:

class Test {
    interface I {
        String f(String x);
    }

    static void foo(I i) {}

    void m() {
        foo((x) -> {
            if (x == null) {
                return;
            } else {
                return x;
            }
        });
    }
}

Der Compiler wird diese Ausgabe geben:

Test.java:9: error: lambda body is neither value nor void compatible
    foo((x) -> {
        ^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

Ich hoffe das hilft.





c# lambda attributes