Generic method with Ti and Ti+1

I have the following generic class using C# 6:

public class IncludeMapper<T1> {

  private readonly Dictionary<String, List<LambdaExpression>> _properties = new Dictionary<String, List<LambdaExpression>>();

  public IncludeMapper<T1> Add<T2, T3>(String property, Expression<Func<T1, T2>> path1, Expression<Func<T2, T3>> path2) {

    if (!_properties.ContainsKey(property))
      _properties.Add(property, new List<LambdaExpression> { path1, path2 });

    return this;

  }

  public IncludeMapper<T1> Add<T2, T3, T4>(String property, Expression<Func<T1, T2>> path1, Expression<Func<T2, T3>> path2, Expression<Func<T3, T4>> path3) {

    if (!_properties.ContainsKey(property))
      _properties.Add(property, new List<LambdaExpression> { path1, path2, path3 });

    return this;

  }

}

The Add method has a few Expressions (paths) which take one Ti and Ti+1.

Is there a way to simplify my code? I will need at least 4 more methods like this until path 7.

Jon Skeet
people
quotationmark

Is there a way to simplify my code?

Well, you could simplify it a bit:

public class IncludeMapper<T1> {

    private readonly Dictionary<String, List<LambdaExpression>> _properties =
        new Dictionary<String, List<LambdaExpression>>();

    private IncludeMapper<T1> AddImpl(
        string property,
        params LambdaExpression[] expressions)
    {
        if (!_properties.ContainsKey(property))
        {
            _properties.Add(property, paths.ToList());
        } 
        return this;
    }

    public IncludeMapper<T1> Add<T2, T3>(
        String property,
        Expression<Func<T1, T2>> path1,
        Expression<Func<T2, T3>> path2) =>
        AddImpl(path1, path2);

    public IncludeMapper<T1> Add<T2, T3, T4>(
        String property,
        Expression<Func<T1, T2>> path1,
        Expression<Func<T2, T3>> path2,
        Expression<Func<T3, T4>> path3) =>
        AddImpl(path1, path2, path3);

    ...
}

You still need another method per "generic arity" that you want to support, but at least the implementation is trivial.

Of course, if you wanted to be able to specify multiple paths, but each path had to be of the same type, that's easy - because then you could use params with a single type of parameter. But the parameter must be a specific Expression<TDelegate> type if you want to be able to use a lambda expression as an argument, and it looks like you want to be able to vary the types involved.

people

See more on this question at Stackoverflow