匿名方法应该按条件返回一个字符串

问题描述 投票:1回答:2

我试图理解在C#中编写匿名方法。但难以取得成功。

请看看我的例子。我正在尝试通过给定条件填充名为Value的属性。

当我写一个私有帮助器方法,它接受一个inputparam int lockCardStatus并返回一个解决方案的字符串,但我的意图是尝试使用“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无法转换为类型字符串,因为它不是委托。

c# properties switch-statement return anonymous-methods
2个回答
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";});

这表明委托类型的显式规范是必要且必不可少的。


2
投票

您尝试做的事情在C#中不可用(因为)无法将switch语句明确地评估为一个返回值。原因是switch case可能包含任意代码而不只是一个表达式。

在C#8中将有一个new way编写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来解决您的问题

© www.soinside.com 2019 - 2024. All rights reserved.