How can I avoid repeated code using lambdas?
You should be able to wrap up your loops in a single method that takes a Func&lt;T&gt; and then do something like this:

public static T1 Do&lt;T1,T2,T3&gt;(Type retryOnExceptionType, Func&lt;T2,T3,T1&gt; action, T2 param1,
                              T3 param2, TimeSpan retryInterval, int retryCount)
{
    var del = new Func&lt;T1&gt;(() =&gt; action(param1, param2));
    return DoLoops&lt;T1&gt;(del, retryOnExceptionType, retryInterval, retryCount);
}


public static T Do&lt;T&gt;(Type retryOnExceptionType, Func&lt;T&gt; action,TimeSpan retryInterval,
                      int retryCount)
{
    return DoLoops&lt;T&gt;(action, retryOnExceptionType, retryInterval, retryCount);
}

private static T DoLoops&lt;T&gt;(Func&lt;T&gt; func, Type retryOnExceptionType,
                            TimeSpan retryInterval, int retryCount)
{
    if (retryInterval == default(TimeSpan))
        retryInterval = TimeSpan.FromSeconds(1);

    var exceptions = new List&lt;Exception&gt;();

    for (int retry = 0; retry &lt; retryCount; retry++)
    {
        try
        {
            return func();
        }
        catch (Exception ex)
        {
            if (!retryOnExceptionType.IsInstanceOfType(ex))
                throw;

            exceptions.Add(ex);
            Thread.Sleep(retryInterval);
        }
    }

    throw new AggregateException(exceptions);
}


The key is in wrapping up your Func&lt;T2, T3, T1&gt; call in a separate Func&lt;T1&gt;, which allows you to pass a parameterless delegate to DoLoops regardless of how many type parameters the original delegate has, since that's the only difference between the original methods.

Even simpler, you can do away with DoLoops and just keep the for loop in the public static T Do&lt;T&gt; overload and Do&lt;T1, T2, T3&gt; can just pass the parameterless delegate it creates into that method:

public static T1 Do&lt;T1,T2,T3&gt;(Type retryOnExceptionType, Func&lt;T2,T3,T1&gt; action, T2 param1,
                              T3 param2, TimeSpan retryInterval, int retryCount)
{
    return Do&lt;T1&gt;(retryOnExceptionType, () =&gt; action(param1, param2),
                  retryInterval, retryCount);
}


public static T Do&lt;T&gt;(Type retryOnExceptionType, Func&lt;T&gt; action, TimeSpan retryInterval,
                      int retryCount)
{
    if (retryInterval == default(TimeSpan))
        retryInterval = TimeSpan.FromSeconds(1);

    var exceptions = new List&lt;Exception&gt;();

    for (int retry = 0; retry &lt; retryCount; retry++)
    {
        try
        {
            return action();
        }
        catch (Exception ex)
        {
            if (!retryOnExceptionType.IsInstanceOfType(ex))
                throw;

            exceptions.Add(ex);
            Thread.Sleep(retryInterval);
        }
    }

    throw new AggregateException(exceptions);
}