1
\$\begingroup\$

I have the following code:

if (isMandatory)
{
    x.MandatoryServices.ForEach(y =>
    {
        if (!y.IsSelectedByUser)
        {
            containsRemovedSrvcs = true;
            return;
        }                            
    });
}
else
{
    x.OptionalServices.ForEach(y =>
    {
        if (!y.IsSelectedByUser)
        {
            containsRemovedSrvcs = true;
            return;
        }
    });
}

I would like to replace it with something more elegant like:

x.{isMandatory ? MandatoryServices : OptionalServices}.ForEach(y =>
{
    if (!y.IsSelectedByUser)
    {
        containsRemovedSrvcs = true;
        return;
    }                            
});

Of course, the compiler doesn't like that. I have seen the GetType().GetProperty().GetValue() approach but I don't really know if that will work since my property is a List. Does anyone know of any better solutions?

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

A possible solution that is very close to your example could be

var services = isMandatory ? x.MandatoryServices
                           : x.OptionalServices;
services.ForEach(y =>
{
    if (!y.IsSelectedByUser)
    {
        containsRemovedSrvcs = true;
        return;
    }                            
});

This require that MandatoryServices and OptionalServices can be assigned to the same variable (i.e. same type, shared interface, ..)


I don't understand why you explicitly return return from your lambda expression, since it does not change anything. The "body" of the lambda will be executed for each element in your collection, regardless of your return.

So you could just remove the return:

if (!y.IsSelectedByUser)
{
    containsRemovedSrvcs = true;
}

And since it looks like you just want to see if any element in the collection is not selected by the user, you can use the Any extension method

containsRemovedSrvcs = services.Any(y => !y.IsSelectedByUser);

Applying all this will give you:

var services = isMandatory ? x.MandatoryServices
                           : x.OptionalServices;
containsRemovedSrvcs = services.Any(y => !y.IsSelectedByUser);
\$\endgroup\$
2
\$\begingroup\$

To achieve that your MandatoryService and OptionalService should share a same base type.

void Main()
{
    var mandatoryServices = new List<MandatoryService> 
        { new MandatoryService { IsSelectedByUser = true } };
    var optionalServices = new List<OptionalService> 
        { new OptionalService { IsSelectedByUser = false } };
    var isMandatory = true;

    var services = isMandatory ? (IEnumerable<IService>)mandatoryServices 
                               : (IEnumerable<IService>)optionalServices;

    if (services.Any(service => !service.IsSelectedByUser))
    {
        containsRemovedSrvcs = true;
    }
}

public interface IService
{
    bool IsSelectedByUser { get; }
}

public class MandatoryService : IService
{
    public bool IsSelectedByUser { get; set; }
}

public class OptionalService : IService
{
    public bool IsSelectedByUser { get; set; }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.