Method for validating properties based on passed conditions I wrote a method for validating properties based on passed conditions. It works well, but declaration takes more space than the actual condition. Is there any way to make it shorter?

public virtual string Validate(string propertyName, params Tuple&lt;Expression&lt;Func&lt;bool&gt;&gt;, string&gt;[] predicates)
{
    if (!ValidationProperties.ContainsKey(propertyName))
        throw new ArgumentException($"No property found with name '{propertyName}'. Make sure you register it first.");

    foreach (var predicate in predicates)
    {
        if (predicate.Item1.Compile().Invoke())
        {
            ValidationProperties[propertyName] = false;
            ValidationChangedEvent?.Invoke(this, false);
            return predicate.Item2;
        }
    }

    ValidationProperties[propertyName] = true;

    if (ValidationProperties.All(pair =&gt; pair.Value))
        ValidationChangedEvent?.Invoke(this, true);

    return null;
}


And here's example of call which I want to be shorter:

 var result = Validate(nameof(FilePath), 
                        new Tuple&lt;Expression&lt;Func&lt;bool&gt;&gt;, string&gt;(() =&gt; string.IsNullOrEmpty(FilePath), "Select a file to load"));


Basically I want to get rid of: new Tuple&lt;Expression&lt;Func&lt;bool&gt;&gt;, string&gt;
The class encapsulating the two properties suggested by @eurotrash is definitely a good idea. I think name ValidationRule should be ok.

class ValidationRule
{
    public ValidationRule(Func&lt;bool&gt; predicate, string message)
    {
        Predicate = predicate;
        Message = message;
    }
    public Func&lt;bool&gt; Predicate { get; }
    public string Message { get; }
}


I'd go further and create a collection so that I can use the collection initializer to specify the rules. This means collection class must implement the IEnumerable&lt;T&gt; interface and some Add(..) method. Then we can use the syntax:

new SomeCollection
{
   Item1, Item2
}


or if the Add(..) requires more then one parameter:

new SomeCollection
{
   { Item1, Item1a },
   { Item2, Item2a },
}


so our new collection is

class ValidationRuleCollection : IEnumerable&lt;ValidationRule&gt;
{
    private readonly List&lt;ValidationRule&gt; _rules = new List&lt;ValidationRule&gt;();

    public ValidationRuleCollection Add(Func&lt;bool&gt; predicate, string message)
    {
        _rules.Add(new ValidationRule(predicate, message));
        return this;
    }

    public IEnumerator&lt;ValidationRule&gt; GetEnumerator() =&gt; _rules.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() =&gt; GetEnumerator();
}


Then you could use it like this

var result = Validate(nameof(FilePath), new ValidationRuleCollection
{
    { () =&gt; string.IsNullOrEmpty(FilePath), "Select a file to load" },
});


You don't need the Expression for it. You're not using it here. It adds overhead but does not have any advantage in this case.



The foreach loop can be replaced with LINQ. You stop at the first true result so use the FirstOrDefault to find it.

var rule = validationRules.FirstOrDefault(x =&gt; x.Predicate());
if (rule != null)
{
    ValidationProperties[propertyName] = false;
    ValidationChangedEvent?.Invoke(this, false);
    return rule.Message;
}