Совсем нубский вопрос по C#
От: yatagarasu Беларусь  
Дата: 19.06.08 11:51
Оценка:
Почему контейнер IList<IList<T>> нельзя привести к типу IList<IEnumrable<T>> и т.п. ?
И как с этим бороться, кроме копирования контейнеров.
Re: Совсем нубский вопрос по C#
От: Ovl Россия  
Дата: 19.06.08 12:40
Оценка: 2 (1) -1
Здравствуйте, yatagarasu, Вы писали:

Y>Почему контейнер IList<IList<T>> нельзя привести к типу IList<IEnumrable<T>> и т.п. ?

Y>И как с этим бороться, кроме копирования контейнеров.


простой ответ — прямой запрет. потому что непонятно как конвертировать обратно базовые типы в производные


class A {}
class B : A {}

//...

List<B> bList;
List<A> aList = bList;

aList.Add(new A()); // и как здесь компилятору конвертнуть A в B  :xz:
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[2]: Совсем нубский вопрос по C#
От: yatagarasu Беларусь  
Дата: 19.06.08 13:46
Оценка:
Здравствуйте, Ovl, Вы писали:

Y>>Почему контейнер IList<IList<T>> нельзя привести к типу IList<IEnumrable<T>> и т.п. ?

Y>>И как с этим бороться, кроме копирования контейнеров.

Ovl>простой ответ — прямой запрет. потому что непонятно как конвертировать обратно базовые типы в производные


Ovl>
Ovl>class A {}
Ovl>class B : A {}

Ovl>//...

Ovl>List<B> bList;
Ovl>List<A> aList = bList;

Ovl>aList.Add(new A()); // и как здесь компилятору конвертнуть A в B  :xz: 

Ovl>


Да, логика понятна. Придется всё хранить базовых типах и самому конвертировать в нужного наследника.
Можно конечно обертку написать, но чет лень =)
Сокрытие реализации, мать её =)
Re: Совсем нубский вопрос по C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 19.06.08 13:49
Оценка: 2 (1)
Здравствуйте, yatagarasu, Вы писали:

Y>Почему контейнер IList<IList<T>> нельзя привести к типу IList<IEnumrable<T>> и т.п. ?


Потому что при добавлении ко- и контравариантности возникают нетривиальные правила контроля безопасности типов, и в текущей версии C# было решено это не поддерживать. Достаточно сказать, что некоторые случаи приведения типов становятся алгоритмически неразрешимыми (undecidable).
В следущей версии C#, возможно, появится некоторая поддержка ко- и контравариантности для интерфейсов и делегатов. Почитайте замечательную серию заметок об этом на блоге Эрика Липперта.
Re[2]: Совсем нубский вопрос по C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.08 15:15
Оценка:
Здравствуйте, nikov, Вы писали:

N>Потому что при добавлении ко- и контравариантности возникают нетривиальные правила контроля безопасности типов, и в текущей версии C# было решено это не поддерживать. Достаточно сказать, что некоторые случаи приведения типов становятся алгоритмически неразрешимыми (undecidable).

N>В следущей версии C#, возможно, появится некоторая поддержка ко- и контравариантности для интерфейсов и делегатов. Почитайте замечательную серию заметок об этом на блоге Эрика Липперта.

Звучит прикольно "Это невозможно... но в следующей версии мы это сделаем".

Хотелось бы услышать о проблемах с безопасностью. Особенно это интересно в свете того, что сам же C# поддерживает (со второй версии) ковариантность для делегатов, а Немерле уже поддерживает ее и для интерфейсов. Например, list (http://nemerle.org/svn/nemerle/trunk/lib/icollection.n) в Немерле реализует ковариантный интерфейс ICovariantList:
  public interface ICovariantList [+T] 
  {
    IsEmpty : bool { get; }
    Head : T { get; }
    CovariantTail : ICovariantList [T] { get; }
  }


Правда, реально ковариантностью интерфейсов лично я так и не воспользовался ни разу.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Совсем нубский вопрос по C#
От: Ziaw Россия  
Дата: 19.06.08 15:32
Оценка:
Здравствуйте, yatagarasu, Вы писали:

Y>Почему контейнер IList<IList<T>> нельзя привести к типу IList<IEnumrable<T>> и т.п. ?

Y>И как с этим бороться, кроме копирования контейнеров.

В некоторых подобных случаях мне помогал такой метод:

    class Program
    {
        class A {}
        class B: A {}
        
        static void Trip<T>(IList<T> list) 
            where T: A
        {
            Console.WriteLine(list.GetType());
        }

        static void Main(string[] args)
        {
            IList<B> list = new List<B>();
            Trip(list);
        }
    }
Re[3]: Совсем нубский вопрос по C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 19.06.08 15:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Звучит прикольно "Это невозможно... но в следующей версии мы это сделаем".

Решается это так же, как и все undecidable проблемы — ставится ограничение на количество итераций алгоритма, при превышении которого выдается невразумительная ошибка (типа Expression is too complex to compile). Трудность в том, как обеспечить, чтобы это возникало только уж на совсем экзотических случаях.

VD>Хотелось бы услышать о проблемах с безопасностью.

Все есть на блоге у Эрика.

VD>Особенно это интересно в свете того, что сам же C# поддерживает (со второй версии) ковариантность для делегатов,

В C# 2.0-3.0 поддерживается не ковариантнось делегатов, а ковариантность возвращаемого значения методов, которые привязываются к делегатам. Делегаты разных типов никогда не совместимы по присваиванию.

VD>а Немерле уже поддерживает ее и для интерфейсов.


Ну, проверь.

#pragma indent
using System.Console;
public interface IN[-U] {}
public interface IC[X] : IN[IN[IC[IC[X]]]] {}
module A
  Main() : void
    def bar : IC[double] = null;
    foo : IN[IC[string]] = bar;
Re[4]: Совсем нубский вопрос по C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 19.06.08 15:35
Оценка:
Здравствуйте, nikov, Вы писали:

N>
N>    foo : IN[IC[string]] = bar;
N>


Последнюю строчку читать:

N>
N>    def foo : IN[IC[string]] = bar;
N>
Re[2]: Совсем нубский вопрос по C#
От: Ziaw Россия  
Дата: 19.06.08 15:46
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>В некоторых подобных случаях мне помогал такой метод:

Впрочем это не тот случай, я поторопился.
Re[4]: Совсем нубский вопрос по C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.08 16:02
Оценка:
Здравствуйте, nikov, Вы писали:

N>Ну, проверь.


N>
N>#pragma indent
N>using System.Console;
N>public interface IN[-U] {}
N>public interface IC[X] : IN[IN[IC[IC[X]]]] {}
N>module A
N>  Main() : void
N>    def bar : IC[double] = null;
N>    foo : IN[IC[string]] = bar;
N>


StackOverflowException.
Но это же банальное зацикливание типов. Причем бессмысленное.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Совсем нубский вопрос по C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.08 16:02
Оценка:
Здравствуйте, nikov, Вы писали:

VD>>Хотелось бы услышать о проблемах с безопасностью.

N>Все есть на блоге у Эрика.

Там черт ногу сломит. 8 тем с кучей осбуждений в каждой.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Совсем нубский вопрос по C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 19.06.08 16:21
Оценка: 6 (1) +1
Здравствуйте, VladD2, Вы писали:

VD>StackOverflowException.

VD>Но это же банальное зацикливание типов. Причем бессмысленное.

Заметь, что это StackOverflowException не в run-time, а при компиляции. Что бы мы ожидали от "умного" компилятора? Что он бы не упал, а сказал бы нам: "Чувак, это же бессмысленное зацикливание типов. Я не буду это компилировать". Undecidablility в данном случае означает, что не существует компилятора, который мог бы безошибочно поставить такой диагноз.

Заметка Эрика об этом: Covariance and Contravariance, Part Eleven: To infinity, but not beyond.
Re[5]: Совсем нубский вопрос по C#
От: IB Австрия http://rsdn.ru
Дата: 19.06.08 18:28
Оценка: +2
Здравствуйте, VladD2, Вы писали:

VD>Там черт ногу сломит. 8 тем с кучей осбуждений в каждой.

Одинадцать. Причем каждая по своей проблеме... =)
Почитай, почитай — оно того стоит..
Мы уже победили, просто это еще не так заметно...
Re: Совсем нубский вопрос по C#
От: MatFiz Россия  
Дата: 24.06.08 04:16
Оценка:
Здравствуйте, yatagarasu, Вы писали:

Y>Почему контейнер IList<IList<T>> нельзя привести к типу IList<IEnumrable<T>> и т.п. ?

Y>И как с этим бороться, кроме копирования контейнеров.

Посмотри на Umbrella project.
Там есть ListAdapter, который может помочь (он "конвертит" List на лету).
How are YOU doin'?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.