Использование пустых указателей на разных платформах

=============

UPDATE: я использовал этот ответ в качестве основы для этой записи в блоге:

Почему ref и параметры не позволяют изменять тип?

См. страницу блога для получения дополнительных комментариев по этой проблеме. Спасибо за отличный вопрос.

=============

Предположим, что у вас есть классы Animal, Mammal, Reptile, Giraffe, Turtle и Tiger, с очевидными отношениями подкласса.

Теперь предположим, что у вас есть метод void M(ref Mammal m). M может читать и записывать m.


Можете ли вы передать переменную типа Animal на M?

blockquote>

№. Эта переменная может содержать Turtle, но M предполагает, что она содержит только млекопитающих. Turtle не является Mammal.

Заключение 1: параметры ref не могут быть сделаны «большими». (Есть больше животных, чем млекопитающих, поэтому переменная становится «больше», потому что она может содержать больше вещей.)


Можете ли вы передать переменную типа Giraffe на M?

blockquote>

№. M может записать на m, а M может захотеть записать Tiger в m. Теперь вы поместили Tiger в переменную, которая фактически имеет тип Giraffe.

Вывод 2: ref параметры не могут быть сделаны «меньше».


Теперь рассмотрим N(out Mammal n).

Можете ли вы передать переменную типа Giraffe на N?

blockquote>

№. N может писать в n, а N может захотеть записать Tiger.

Заключение 3: out параметры не могут быть сделаны «меньше».


Можете ли вы передать переменную типа Animal на N?

blockquote>

Хмм.

Ну, почему бы и нет? N не может читать из n, он может писать только ему, не так ли? Вы записываете Tiger в переменную типа Animal, и все вы настроены, верно?

Неверно. Правило не "N может писать только n".

Правила кратко:

1) N должен записать в n, прежде чем N вернется нормально. (Если N выбрасывает, все ставки отключены.)

2) N должен что-то записать в n, прежде чем он что-то прочитает из n.

разрешает эту последовательность событий:

  • Объявить поле x типа Animal.
  • Пропустить x как параметр out до N.
  • N записывает Tiger в n, который является псевдонимом для x.
  • В другом потоке кто-то пишет Turtle в x.
  • N пытается прочитать содержимое n и обнаруживает Turtle в том, что, по его мнению, является переменной типа Mammal.

Очевидно, мы хотим сделать это незаконным.

Заключение 4: out параметры не могут быть сделаны «большими».


Окончательное заключение : Ни параметры ref, ни out могут варьироваться в зависимости от их типа. Иначе говоря, нужно разбить безопасную безопасность типа.

Если эти вопросы в теории базового типа вас интересуют, подумайте о том, чтобы прочитать мою серию о том, как ковариация и контравариантность работают в C # 4.0 .

13
задан Mohit Jain 25 February 2015 в 15:34
поделиться