C# Dynami c приведение превосходит ошибку несоответствия типов для другого параметра - PullRequest
0 голосов
/ 26 апреля 2020

Когда я приводю переменную к типу dynamic перед передачей ее в типовой параметр функции типа c, следующий параметр обходится при проверке типа.

В приведенном ниже фрагменте как первый вызов метода Check, экранирующий компиляцию?
Приведение (dynamic) выполняется только к первому аргументу (где Type1 передается Interface1). Но второй параметр, где Type1 передается Interface2, не является ошибкой при компиляции.

interface Interface1 { }
interface Interface2 { }

class Type1 : Interface1 { }
class Type2 : Interface2 { }

class Program
{
    public static void Check<T1, T2>(T1 obj1, T2 obj2) where T1 : Interface1 where T2 : Interface2
    {
    }

    static void Main(string[] args)
    {
        Check((dynamic)new Type1(), new Type1()); //passes compliation and fails in runtime

        Check(new Type1(), new Type1()); //fails in compilation
    }
}

Ответы [ 2 ]

2 голосов
/ 26 апреля 2020

Когда вы используете any dynamici c значения в качестве аргумента в вызове метода, метод динамически привязывается. Если вы используете типовой вывод generic c на всех (независимо от того, участвует ли в этом значение dynamici c), ограничения типа generi c не проверяются.

Вот немного более простая версия того, что вы видите:

using System;

class Test
{
    static void Main()
    {
        dynamic d = 1;
        // Compiles
        M(d, 0);

        // Doesn't compile - explicit type argument
        M<int>(d, 0);
    }

    static void M<T>(object ignored, T value) where T : class
    {
    }    
}

Компилятор выполнит некоторую проверку, но он относительно консервативен с точки зрения того, что он проверяет. По сути, если вы погружаетесь в сферу динамического связывания c, вы должны быть действительно осторожными и ожидать, что все может сделать не так много проверки типов, как вы думаете.

(Если я правильно помню, spe c довольно точно не говорит о том, сколько проверки выполняется для динамически связанных операций, так что вы можете потенциально оказаться в ситуации, когда он компилируется с некоторыми компиляторами, но не с другими.)

1 голос
/ 26 апреля 2020

Использование dynamic приводит к тому, что общая проверка типа c откладывается до времени выполнения. Если какой-либо параметр равен dynamic, то все это откладывается, поэтому в первом операторе один dynamic вызывает отсрочку.

Без него во втором операторе проверка выполняется во время компиляции. время и так терпит неудачу как ошибка компилятора.

В обоих случаях вызов недопустим: obj2 не может иметь значение Type1, поскольку Type1 не реализует Interface2. Вопрос только в том, когда ошибка обнаружена.

...