C # Смешение неявно типизированной переменной с динамическим - PullRequest
0 голосов
/ 26 февраля 2019

Если вы запустите TestClass.Test (), вы получите исключение RuntimeBinderException.Все начинается с var str = DoSomething(obj);, неявно набирающего динамический, а не строковый тип.Может кто-нибудь объяснить, что здесь происходит?Почему RequiresString(str); работает?Я понимаю, что вы не можете вызывать методы расширения для динамических объектов, но все это кажется мне немного грязным и сломанным.Все это прекрасно компилируется, несмотря на очевидные несоответствия типов, а затем дает сбой во время выполнения.

public static class ExtensionTest
{
    public static string ToJsonTest(this object x)
    {
        return string.Empty;
    }
}
public static class TestClass
{
    public static void Test()
    {
        dynamic obj = new ExpandoObject();
        obj.var1 = "hello";

        var str = DoSomething(obj);
        var testObj = RequiresString(str);
        var json = testObj.ToJsonTest();
    }
    public static string DoSomething(object x)
    {
        return string.Empty;
    }
    public static TestObj RequiresString(string x)
    {
        return new TestObj();
    }
    public class TestObj
    {
        public int Prop1 { get; set; }
    }
}

1 Ответ

0 голосов
/ 26 февраля 2019

Вызов RequiresString содержит dynamic аргументов, поэтому он разрешается во время выполнения с использованием фактического типа аргумента.Фактический тип, возвращаемый DoSomething, равен string, поэтому средство связывания во время выполнения ищет RequiresString(string), которое может быть успешно найдено как TestClass.RequiresString.Пока все хорошо.

Следующий вызов testObj.ToJsonTest() завершается неудачно, как вы уже упоминали, потому что методы расширения для dynamic target не разрешены , поэтому следующий вызов завершится неудачей.

Да, это может показаться немного грязным, потому что нет (почти) никаких проверок во время компиляции, когда задействованы dynamic s, очень похоже на слабо типизированные языки сценариев.Вот почему я бы посоветовал использовать dynamic, только если это действительно необходимо и в самом узком контексте;в частности, я бы сказал, что dynamic не должно быть видно на публичной поверхности класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...