C # Недопустимая ошибка отклонения при наличии параметра метода out [duplicate]

Если мы рассмотрим общие сценарии, в которых может быть выбрано это исключение, доступ к свойствам с объектом вверху.

Пример:

string postalcode=Customer.Address.PostalCode; 
//if customer or address is null , this will through exeption

здесь, если адрес имеет значение null, то вы получите NullReferenceException.

Итак, в качестве практики мы всегда должны использовать проверку нуля, прежде чем обращаться к свойствам в таких объектах (особенно в общих)

string postalcode=Customer?.Address?.PostalCode;
//if customer or address is null , this will return null, without through a exception
11
задан skaffman 20 May 2010 в 18:40
поделиться

4 ответа

36
ответ дан Eric Lippert 23 August 2018 в 21:54
поделиться
  • 1
    Привет Эрик, мне нужно немного поспать, прежде чем я смогу заверить вас в преданном обсуждении. На данный момент, спасибо миллион. Ваша страсть к вашей работе, очевидно, непреодолима, непревзойденна (если есть слово как таковое). Хотя я действительно ценю причины невероятности наличия типа ref / out как вариантного параметра или типа возврата, я перечитаю ваш ответ, когда я хорошо отдохну, чтобы оправдать усилия, которые вы положили Спасибо много раз снова. – Water Cooler v2 21 May 2010 в 01:12
  • 2
    Прохладное объяснение. Я только что нашел эту нить после поиска. Первоначально я думал, что общий тип T (принадлежащий типу делегата), который использовался только в параметре out «позиция», должен быть помечен как covariant . Я думал, что объяснение, которое не будет компилироваться, было вопросом, что ref и out являются «теми же». за кулисами. Но ваш последний пример убеждает меня. Это также объясняет, почему для обычных вызовов методов (забыть делегатов и общую дисперсию, подумайте о C # версии 1.2) переменная, помещенная в параметр out, должна точно указать тип (будучи less производным типом не является ОК). – Jeppe Stig Nielsen 6 September 2012 в 15:50
  • 3
    @JeppeStigNielsen: По идее, компилятору должно быть разрешено передавать переменную Foo типа Animal в выходной параметр типа Dog, передавая временную переменную типа Dog в подпрограмму, а затем копируя это до Foo после того, как существует обычная процедура. Концептуально это то, что out должно означать так или иначе. К сожалению, создатели .net не захотели требовать, чтобы языки реализовали параметры out, и поэтому .net не может делать какие-либо предположения, которые могли бы сломаться, если вызывающий объект функции обработал out как ref. – supercat 25 November 2012 в 19:45
  • 4
    @supercat Ты прав. Но только если он был всегда незаконным для метода "read & quot;" его собственный параметр out. Но, как указывает Липперт, это не так. Когда вы читаете & quot; из вашего параметра out вы нарушаете ковариацию. На самом деле, если параметр out (передан) поле какого-либо класса, другой поток, отличный от вашего, может изменить ссылку параметра out, чтобы указать на новый объект другого типа времени выполнения, в то время как ваш метод запущен. – Jeppe Stig Nielsen 26 November 2012 в 14:37
  • 5
    Описывается тип supercat refness, называемый «копирование в копии», и есть языки, которые его используют. Эта идея передачи переменной по ссылке или, что то же самое, сделать псевдоним переменной, на мой взгляд, является примером высокоэффективной детали реализации, которая появляется как запутанная языковая функция. Тот факт, что многие люди не понимают, как это работает, указывает на то, что это, может быть, не отличная функция. – Eric Lippert 26 November 2012 в 18:12
1
ответ дан Franci Penov 23 August 2018 в 21:54
поделиться
  • 1
    Понимаю. Большое спасибо. :-) – Water Cooler v2 20 May 2010 в 19:10
  • 2
    Это неверно. Вторая линия вполне законна. Вы правы, что первая строка является незаконной. – Eric Lippert 20 May 2010 в 21:26
  • 3
    @Eric - ah, вторая строка является законной, поскольку параметр R generic не помечен как вариант. это правильно? – Franci Penov 20 May 2010 в 22:10
  • 4
    Большое спасибо, Эрик. Я должен был сам это понять, если бы у меня были навыки терпения и корректуры. Но позвольте мне заверить вас, я полностью слежу за причинами ошибки, которую вы пролили свет. – Water Cooler v2 21 May 2010 в 00:39
0
ответ дан Michael Damatov 23 August 2018 в 21:54
поделиться

Можно использовать ковариацию без параметров, но вам нужны две структуры. Например, вы можете поместить параметр out в метод расширения:

SELECT Name, Value
FROM (
  SELECT Name, Value, RANK() OVER (ORDER BY Value DESC) AS rk
  FROM table
) t
WHERE rk <= 3
0
ответ дан Colin 6 November 2018 в 04:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: