The main problem is that the Tuple family is not covariant in its type arguments. This cannot be, because it is a class. A version of an interface or a delegate can be created that would be covariant, since there are no elements that accept type parameters at input positions.
This is easiest to see with Tuple<T1> :
Tuple<string> stringTuple = Tuple.Create("Foo"); Tuple<object> objectTuple = stringTuple;
This call:
Tuple.Create(d1, d2);
... prints both arguments of type Dictionary<string, int> , so you are trying to convert from Tuple<Dictionary<string, int>, Dictionary<string, int>> to Tuple<IDictionary<string, int>, IDictionary<string, int>> which does not work.
The as version changes the types of the arguments, so type inference gives the required type arguments, but it would be easier to just write the type arguments directly and completely exclude the output, according to Sebastian's answers:
Tuple.Create<IDictionary<string, int>, IDictionary<string, int>>(d1, d2)
If you use var at this point, this is not so bad:
var x = Tuple.Create<IDictionary<string, int>, IDictionary<string, int>>(d1, d2);
Now the type x will be the Tuple<IDictionary<string, int>, IDictionary<string, int>> that you want.
EDIT: As noted in the comments, you can simply use the constructor at this point:
var x = new Tuple<IDictionary<string, int>, IDictionary<string, int>>(d1, d2);