Явное приведение возвращаемого значения динамического метода в методе не позволяет вызывать метод расширения - PullRequest
5 голосов
/ 26 октября 2011

Следующий код демонстрирует мой вопрос:

public class DynamicExample
{
    public void DoSomething()
    {
        var x = new ExpandoObject();
        dynamic d = x;
        d.GetString = (Func<string>)(() => "Some Value");

        d.GetString().SomeStringExtension(); // Doesn't work - expected
        ((string)d.GetString()).SomeStringExtension(); // Works - expected
        Build(d).SomeStringExtension(); // Doesn't work - unexpected?
    }

    private static string Build(dynamic d)
    {
        return (string)d.GetString();
    }
}

public static class StringExtensions
{
    public static int SomeStringExtension(this string s)
    {
        return s.Length;
    }
}

Вопрос в том, почему для компилятора существует разница между приведением типа inline к вызову метода расширения и перемещением этого преобразования в отдельный метод?

Ответы [ 2 ]

5 голосов
/ 26 октября 2011

Build(d) по-прежнему является динамическим выражением - тип метода времени компиляции dynamic, хотя you может точно видеть, что происходит.Это означает, что методы расширения не будут работать.

По существу, компилятор следует достаточно простым правилам для определения типа выражения, и почти любое выражение, включающее dynamic, в конечном итоге считаетсякак динамическое выражение.Исключениями являются:

  • d is SomeType (всегда считается bool)
  • Приведения, как прямые, так и с использованием as

Это все, насколько я помню, хотя я мог ошибаться ...

Теперь язык мог бы быть спроектирован так, чтобы этот случай статически разрешалсявызов Build как единственный разумный - в конце концов, d не может иметь любого типа, который бы изменял, какой метод вызывается, - но указание точных правил для этого сделало быспецификация языка (и компилятор) значительно сложнее при сравнительно небольшом выигрыше.

5 голосов
/ 26 октября 2011

Если вы наведите курсор мыши на Build(d) в VS2010, вы увидите, что все выражение считается динамическим и должно разрешаться во время выполнения.Таким образом, он не может связываться с методом расширения (который в противном случае произошел бы во время компиляции.)разрешение перегрузки не может быть не выполняется, и поэтому тип возврата метода не может быть также неизвестен.

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