Переключатель C# в лямбда-выражении
возможно ли иметь переключатель в лямбда-выражении ? Если нет, то почему ? Resharper отображает его как ошибку.
5 ответов
вы можете в блоке оператора Lambda:
Action<int> action = x =>
{
switch(x)
{
case 0: Console.WriteLine("0"); break;
default: Console.WriteLine("Not 0"); break;
}
};
но вы не можете сделать это в "одном выражении лямбда", поэтому это недопустимо:
// This won't work
Expression<Func<int, int>> action = x =>
switch(x)
{
case 0: return 0;
default: return x + 1;
};
это означает, что вы не можете использовать switch в дереве выражений (по крайней мере, как генерируется компилятором C#; я считаю, что .NET 4.0, по крайней мере, поддерживает его в библиотеках).
в чистом Expression
(в .NET 3.5) самое близкое, что вы можете получить, это составное условие:
Expression<Func<int, string>> func = x =>
x == 1 ? "abc" : (
x == 2 ? "def" : (
x == 3 ? "ghi" :
"jkl")); /// yes, this is ugly as sin...
не весело, особенно когда это становится сложным. Если вы имеете в виду выражение lamda с телом оператора (только для использования с LINQ-to-Objects), то все законно внутри фигурных скобок:
Func<int, string> func = x => {
switch (x){
case 1: return "abc";
case 2: return "def";
case 3: return "ghi";
default: return "jkl";
}
};
конечно, вы можете передать работу на аутсорсинг; например, LINQ-to-SQL позволяет сопоставить скалярный UDF (в базе данных) с методом в контексте данных (это не фактически используется) - например:
var qry = from cust in ctx.Customers
select new {cust.Name, CustomerType = ctx.MapType(cust.TypeFlag) };
здесь MapType
является UDF, который выполняет работу на сервере БД.
Да, это работает, но вы должны поставить свой код в блок. Пример:
private bool DoSomething(Func<string, bool> callback)
{
return callback("FOO");
}
тогда назвать это:
DoSomething(val =>
{
switch (val)
{
case "Foo":
return true;
default:
return false;
}
});
Хм, я не вижу причин, почему это не должно работать. Просто будьте осторожны с синтаксис
param => {
// Nearly any code!
}
delegate (param) {
// Nearly any code!
}
param => JustASingleExpression (No switches)
Я тоже проверил: -)
[Test]
public void SwitchInLambda()
{
TakeALambda(i => {
switch (i)
{
case 2:
return "Smurf";
default:
return "Gnurf";
}
});
}
public void TakeALambda(Func<int, string> func)
{
System.Diagnostics.Debug.WriteLine(func(2));
}
работает просто отлично (выходы "Smurf")!