/ / Expression.Switch () che lotta per l'implementazione del caso - c #, espressione

Expression.Switch () alle prese con l'implementazione del caso - c #, espressione

Sto cercando di implementare il Expression.Switch() per creare un'istruzione switch all'interno delle mie espressioni. Sto lottando con alcuni problemi.

Ho creato un piccolo esempio che solleva l'eccezione. Lo switch utilizza una stringa per cambiare i casi e in quel caso assegnerà una variabile.

Ecco un po 'di codice che solleverà l'eccezione:

// an int variable
var var1 = Expression.Parameter(typeof(int));
// a string variable
var var2 = Expression.Parameter(typeof(string));

var cases = new[]
{
// the first case "SwitchCaseValue1" should write the int value 1 into variable var1
Expression.SwitchCase(Expression.Assign(var1, Expression.Constant(1)), Expression.Constant("SwitchCaseValue1")),
// the second case "SwitchCaseValue2" should write the string value "Example" into variable var2
Expression.SwitchCase(Expression.Assign(var2, Expression.Constant("Example")), Expression.Constant("SwitchCaseValue2"))
};

Expression.Switch(Expression.Constant("SwitchValue"), cases);

Ciò solleverà questa eccezione: All case bodies and the default body must have the same type.

Penso che questo si riferisca al Assign restituendo per case 1 un int e per case 2 una stringa. Come posso restituire nulla?


Se cambio il var2 digitare int:

// an int variable
var var1 = Expression.Parameter(typeof(int));
// a string variable
var var2 = Expression.Parameter(typeof(int));

var cases = new[]
{
// the first case "SwitchCaseValue1" should write the int value 1 into variable var1
Expression.SwitchCase(Expression.Assign(var1, Expression.Constant(1)), Expression.Constant("SwitchCaseValue1")),
// the second case "SwitchCaseValue2" should write the string value "Example" into variable var2
Expression.SwitchCase(Expression.Assign(var2, Expression.Constant(2)), Expression.Constant("SwitchCaseValue2"))
};

Expression.Switch(Expression.Constant("SwitchValue"), cases);

Solleva un'eccezione: Default body must be supplied if case bodies are not System.Void.

Quindi ho cambiato: l'ultima riga in Expression.Switch(Expression.Constant("SwitchValue"), Expression.Constant(0), cases);

Questo compilerà. ma non è quello che sto cercando ...


C'è un altro modo per risolvere questa prima soluzione senza implementare un codice aggiuntivo per restituire lo stesso tipo?

Non mi piacciono le soluzioni come la selezione di un valore restituito insignificante, come:

// an int variable
var var1 = Expression.Parameter(typeof(int));
// a string variable
var var2 = Expression.Parameter(typeof(string));

var cases = new[]
{
// the first case "SwitchCaseValue1" should write the int value 1 into variable var1
Expression.SwitchCase(
Expression.Block(
Expression.Assign(var1, Expression.Constant(1)),
// return a boolean
Expression.Constant(true)),
Expression.Constant("SwitchCaseValue1")),
// the second case "SwitchCaseValue2" should write the string value "Example" into variable var2
Expression.SwitchCase(
Expression.Block(
Expression.Assign(var2, Expression.Constant("Example")),
// return a boolean
Expression.Constant(true)),
Expression.Constant("SwitchCaseValue2"))
};


Expression.Switch(Expression.Constant("SwitchValue"), Expression.Constant(false), cases);

Comprendo la logica delle espressioni e la restituzione di un valore. Ma c'è un modo per evitare l'implementazione di codice insignificante?

risposte:

3 per risposta № 1

Ho trovato la risposta da solo

Il Expression.Switch() ha un sovraccarico Switch(Type type, Expression switchValue, Expression defaultBody, MethodInfo comparison, IEnumerable<SwitchCase> cases);

Quando si utilizza questo sovraccarico e il passaggio typeof(void) nel parametro type, lo accetterà.

MSDN: "Tutti gli oggetti SwitchCase in un oggetto SwitchExpression devono avere lo stesso tipo, a meno che SwitchExpression non abbia il tipo vuoto." Non ho fatto il collegamento tra il Tipo di SwitchExpression e un sovraccarico contenente a genere parametro.

Questo farà il lavoro:

// an int variable
var var1 = Expression.Parameter(typeof(int));
// a string variable
var var2 = Expression.Parameter(typeof(string));

var cases = new[]
{
// the first case "SwitchCaseValue1" should write the int value 1 into variable var1
Expression.SwitchCase(
Expression.Assign(var1, Expression.Constant(1)),
Expression.Constant("SwitchCaseValue1")),
// the second case "SwitchCaseValue2" should write the string value "Example" into variable var2
Expression.SwitchCase(
Expression.Assign(var2, Expression.Constant("Example")),
Expression.Constant("SwitchCaseValue2"))
};

Expression.Switch(typeof(void), Expression.Constant("SwitchValue"), null, null, cases);