匿名方法应该 return 条件字符串
Anonymous method should return a string by condition
我正在尝试了解在 C# 中编写匿名方法。
但是很难成功。
请看我的例子。
我正在尝试根据给定条件填充 属性 命名值。
当我编写一个私有辅助方法时,它接受一个输入参数 int lockCardStatus 和 returns 一个字符串,这将是一个解决方案,但我的意图是像这样用 "quickshot" 尝试这个:
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 Expression cannot be converted to type string because it is not a delgate.
错误的产生是因为编译器解释了这一行:
Value = y => {...}
作为作业。它认为您想将 lambda 表达式分配给 Value
。但是类型不匹配! Value
是 string
而不是任何类型的代表。有关详细信息,请参阅 Compiler Error CS1660
您真正想要的是执行此 lambda 并分配结果值。为此,您可以使用 Func<string>
在创建 lambda 时定义委托和 return 值。并像在普通方法调用中一样使用 ( )
括号当场执行它:
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!
};
突然间这些东西变得可编译了。
编辑:
显然,编译器无法推断出 return 类型,因此无法自行指定委托类型。这可以通过这个例子来说明:
var asd = () => { return "XXX"; };
此行导致错误:
CS0815 Cannot assign lambda expression to an implicitly-typed variable
但是委托类型的明确说明解决了这个错误:
var asd = new Func<string>(() => { return "XXX";});
这表明委托类型的显式规范是必要和必要的。
您尝试执行的操作在 C# 中(尚)不可用,因为无法将 switch 语句明确地评估为一个 return 值。这样做的一个原因是 switch case 可能包含任意代码而不仅仅是一个表达式。
将有一个 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
来解决您的问题
我正在尝试了解在 C# 中编写匿名方法。 但是很难成功。
请看我的例子。 我正在尝试根据给定条件填充 属性 命名值。
当我编写一个私有辅助方法时,它接受一个输入参数 int lockCardStatus 和 returns 一个字符串,这将是一个解决方案,但我的意图是像这样用 "quickshot" 尝试这个:
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 Expression cannot be converted to type string because it is not a delgate.
错误的产生是因为编译器解释了这一行:
Value = y => {...}
作为作业。它认为您想将 lambda 表达式分配给 Value
。但是类型不匹配! Value
是 string
而不是任何类型的代表。有关详细信息,请参阅 Compiler Error CS1660
您真正想要的是执行此 lambda 并分配结果值。为此,您可以使用 Func<string>
在创建 lambda 时定义委托和 return 值。并像在普通方法调用中一样使用 ( )
括号当场执行它:
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!
};
突然间这些东西变得可编译了。
编辑:
显然,编译器无法推断出 return 类型,因此无法自行指定委托类型。这可以通过这个例子来说明:
var asd = () => { return "XXX"; };
此行导致错误:
CS0815 Cannot assign lambda expression to an implicitly-typed variable
但是委托类型的明确说明解决了这个错误:
var asd = new Func<string>(() => { return "XXX";});
这表明委托类型的显式规范是必要和必要的。
您尝试执行的操作在 C# 中(尚)不可用,因为无法将 switch 语句明确地评估为一个 return 值。这样做的一个原因是 switch case 可能包含任意代码而不仅仅是一个表达式。
将有一个 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