我试图理解用C#编写匿名方法。 但是很难取得成功。
请查看我的示例。 我正在尝试通过给定条件填充名为Value的属性。
当我编写一个私有的helper方法时,该方法将一个inputparam int lockCardStatus并返回一个字符串,这将是一个解决方案,但我的意图是尝试使用“快速快照”进行尝试,如下所示:
MailMessageTextPlaceholders = new List<MailMessageTextPlaceholder>
{
new MailMessageTextPlaceholder
{
PlaceholderName = "status",
Value = y =>
{
switch (_lockCard.Status)
{
case (int)LockCard.LockCardStatus.Done :
return "Is Done";
case (int)LockCard.LockCardStatus.Pending :
return "Is in Pending status";
case (int)LockCard.LockCardStatus.Open :
return "Has been created";
default:
return "No status yet!";
}
}
}
}
不幸的是编译器说:
Lambda表达式不能转换为字符串类型,因为它不是委托。
答案 0 :(得分:3)
由于编译器解释此行而出现错误:
Value = y => {...}
作为作业。它认为您想将lambda表达式分配给Value
。但是类型不匹配! Value
是string
,而不是任何类型的委托。有关详细信息,请参见Compiler Error CS1660
您真正想要的是执行此lambda并分配结果值。为此,您可以使用Func<string>
在创建lambda时定义委托和返回值。然后使用( )
括号立即执行它,就像在常规方法调用中一样:
MailMessageTextPlaceholder hodler = new MailMessageTextPlaceholder()
{
Value = new Func<string>(() =>
{
switch (_lockCard.Status)
{
case (int)LockCard.LockCardStatus.Done:
return "Is Done";
case (int)LockCard.LockCardStatus.Pending:
return "Is in Pending status";
case (int)LockCard.LockCardStatus.Open:
return "Has been created";
default:
return "No status yet!";
}
})() // <- this executes the method!
};
突然间,这些东西变得可编译了。
编辑:
显然,编译器无法推断返回类型,因此无法自行指定委托类型。此示例可以说明:
var asd = () => { return "XXX"; };
此行导致错误:
CS0815无法将lambda表达式分配给隐式类型的变量
但是委托类型的明确指定可以解决此错误:
var asd = new Func<string>(() => { return "XXX";});
这表明委托类型的显式规范是必要且必要的。
答案 1 :(得分:2)
您正在尝试执行的操作在C#中尚不可用(因为尚未将switch语句明确地评估为一个返回值)。这样做的原因是切换条件可能包含任意代码,而不仅仅是一个表达式。
将有new way的C#8编写switch语句使您的代码成为可能。
您可以通过创建辅助方法来解决问题:
MailMessageTextPlaceholders = new List<MailMessageTextPlaceholder>
{
new MailMessageTextPlaceholder
{
PlaceholderName = "status",
Value = GetStatusDescription(_lockCard.Status)
}
}
string GetStatusDescription(LockCard.LockCardStatus status)
{
switch (status)
{
case (int)LockCard.LockCardStatus.Done :
return "Is Done";
case (int)LockCard.LockCardStatus.Pending :
return "Is in Pending status";
case (int)LockCard.LockCardStatus.Open :
return "Has been created";
default:
return "No status yet!";
}
}
并且辅助方法可以是local function
如果您仍然真的希望内联字符串映射,则可以嵌套三元运算符。
MailMessageTextPlaceholders = new List<MailMessageTextPlaceholder>
{
new MailMessageTextPlaceholder
{
PlaceholderName = "status",
Value =
status == LockCard.LockCardStatus.Done
? "Is Done";
: status == LockCard.LockCardStatus.Pending
? "Is in Pending status"
: status == LockCard.LockCardStatus.Open
? "Has been created"
: "No status yet!";
}
}
使用三元运算符时,C#将能够明确评估结果,这使编译器感到满意。
您还可以通过将description attributes添加到enum