Ваш конструктор будет зацикливаться до тех пор, пока не появится в стеке. Это потому, что он продолжает называть себя рекурсивно. Попробуйте разделить его:
public Pair(TValue1 value1, TValue2 value2)
: this(value1, value2, () => toStringFunc(this)) { }
public Pair(TValue1 value1, TValue2 value2, Func<Pair<TValue1, TValue2>, String> toStringFunc)
{ /* some actual logic */ }