Search code examples
c#propertiesswitch-statementreturnanonymous-methods

Anonymous method should return a string by condition


I'm trying to understand writing anonymous Methods in C#. But having trouble to achieve a success.

Please have a look at my example. I'm trying to fill a property named Value by given conditions.

When I would write a private helper method which takes an inputparam int lockCardStatus and returns a string that would be a solution but my intention is to try this with a "quickshot" like so:

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!";
            }
        }
    }
}

Unfortunately the compiler says:

Lambda Expression cannot be converted to type string because it is not a delgate.


Solution

  • The error arises because the compiler interprets this line:

    Value = y => {...}
    

    as an assignment. It thinks you want to assign the lambda expression to Value. But the types don't match! Value is a string and not a delegate of any kind. For detailed information see Compiler Error CS1660

    What you actually want is to execute this lambda and assign the resulting value. To accomplish that you can define the delegate and the return value at creation of the lambda using Func<string>. and execute it on the spot by using the ( ) parentheses like in a normal method call:

    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!
        };
    

    And suddenly this stuff becomes compileable.

    EDIT:

    Apparently the compiler is not able to infer the return type and thus specify the delegate type on its own. This can be illustrated by this example:

    var asd = () => { return "XXX"; };
    

    This line results in the error:

    CS0815 Cannot assign lambda expression to an implicitly-typed variable

    But excplicit specification of the delegate type resolves this error:

    var asd = new Func<string>(() => { return "XXX";});
    

    This indicates that the explicit specification of the delegate type is necessary and essential.