Почему TRest в Tuple <T1 ... TRest> не ограничен? - PullRequest
5 голосов
/ 08 июня 2010

В кортеже, если у вас более 7 предметов, вы можете предоставить восьмой предмет, который является еще одним кортежем и определить до 7 предметов, а затем еще один кортеж как восьмой, включающий и выключающий линию.Тем не менее, нет никаких ограничений на 8-й элемент во время компиляции.Например, это допустимый код для компилятора:

var tuple = new Tuple<int, int, int, int, int, int, int, double>
                (1, 1, 1, 1, 1, 1, 1, 1d);

Несмотря на то, что в документации по Intellisense сказано, что TRest должен быть Tuple.Вы не получаете никакой ошибки при написании или построении кода, он не проявляется до времени выполнения в форме ArgumentException.

Вы можете примерно реализовать кортеж за несколько минут, в комплекте с 8-м предметом, ограниченным кортежем.Мне просто интересно, почему это было оторвано от текущей реализации?Возможно ли проблема прямой совместимости, когда они могли бы добавить больше элементов с гипотетическим C # 5?

Короткая версия грубая реализация

interface IMyTuple { }

class MyTuple<T1> : IMyTuple
{
    public T1 Item1 { get; private set; }
    public MyTuple(T1 item1) { Item1 = item1; }
}

class MyTuple<T1, T2> : MyTuple<T1>
{
    public T2 Item2 { get; private set; }
    public MyTuple(T1 item1, T2 item2) : base(item1) { Item2 = item2; }
}

class MyTuple<T1, T2, TRest> : MyTuple<T1, T2> where TRest : IMyTuple
{
    public TRest Rest { get; private set; }
    public MyTuple(T1 item1, T2 item2, TRest rest)
        : base(item1, item2)
    {
        Rest = rest;
    }
}

...

var mytuple = new MyTuple<int, int, MyTuple<int>>
                 (1, 1, new MyTuple<int>(1)); // legal
var mytuple2 = new MyTuple<int, int, int>(1, 2, 3); // illegal at compile time

Ответы [ 2 ]

7 голосов
/ 08 июля 2010

Это ограничение системы типов. ITuple это внутренний интерфейс. Если бы это было общее ограничение, оно должно быть общедоступным, что позволило бы каждому реализовать свой собственный ITuple, который не мог иметь ничего общего с кортежами. Ограничение его внутренним позволяет команде BCL гарантировать, что это на самом деле своего рода кортеж, но в результате TRest становится немного менее безопасным во время компиляции, чем могло бы быть.

1 голос
/ 08 июня 2010

Гипотетическое ограничение ITuple не будет действительно ограничивать его как кортеж [1], не так ли? Просто класс, который реализует ITuple.

[1] - я определяю "кортеж" как один из Tuple<> классов, предоставляемых BCL.

...