Как обойти ограничения вывода типа в универсальных методах

Я пытаюсь реализовать общий метод, который предназначен для преобразования объектов типа Tuple в объекты типа Tuple Тип <Предок> . Я столкнулся с проблемой, которая, похоже, является ограничением языка C #.

using System;

namespace Samples
{
    public static class TupleExtensions
    {
        public static Tuple<SuperOfT1> ToSuper<T1, SuperOfT1>(this Tuple<T1> target)
            where T1 : SuperOfT1
        {
            return new Tuple<SuperOfT1>(target.Item1);
        }
    }

    public interface Interface { }

    public class Class : Interface { }

    static class Program
    {
        static void Main()
        {
            var tupleWithClass = new Tuple<Class>(new Class());

            // Next instruction lead the compilation to error. :( The compiler doesn't try to infer types if at least one of generic type arguments is explicitly declared.
            var tupleWithInterfaceIncorrect = tupleWithClass.ToSuper<Interface>();

            // Next instruction is correct. But it looks ugly.
            var tupleWithInterfaceCorrect = tupleWithClass.ToSuper<Class, Interface>();

            // The code I try to write in my software is even worse:
            // I need to declare more types explicitly, because my actual tuple has more dimensions.
            // var myTupleInProduction = tuple.ToSuper<Class1<T>, Class2<T>, Interface1<T>, Interface2<T>>();
            // This code is VB.NET-like (too verbose). The problem is compounded by the fact that such code is used in many places.

            // Can I rewrite my TupleExtensions to provide more laconic code like that:
            // var myTupleInProduction = tuple.ToSuper<Interface1<T>, Interface2<T>>();

            Console.ReadKey();
        }
    }
}

Вопросы:

  1. Вы знаете, как заставить этот код работать (учтите важный комментарий в примере кода)?
  2. Если нет, то как вы порекомендуете мне это исправить? Я хочу, чтобы код был простым и понятным.
7
задан Thomas Levesque 21 August 2011 в 18:16
поделиться