“Динамический” тип может варьироваться безопасно по <динамичному> универсальному набору?

На основе моего ответа на этот вопрос я хочу проверить что-то на своем понимании предстоящего dynamic введите для C# 4.

В этом случае у нас есть набор, который представляет поля в записи, которую вытягивают от неизвестной таблицы базы данных. Более старый код (pre-.Net 4) требует, чтобы такой набор содержал объекты типа Object. Достоинства такого набора в стороне, я задаюсь вопросом о том, что происходит, когда Вы изменяетесь Object кому: dynamic.

С одной стороны, я ожидаю, что, так как вещи для динамических типов все разработаны во времени выполнения, которым все должно быть очень хорошо, пока программист не делает опечаток или ошибок об ожидаемом типе конкретного объекта в наборе.

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

10
задан Community 23 May 2017 в 10:33
поделиться

4 ответа

Вот соответствующий бит из блога Сэма, который кратко рассказывает о политике кэширования.

http://blogs.msdn.com/samng/archive/2008/10/29/dynamic-in-c.aspx

DLR проверяет кеш, чтобы увидеть, если Данные действия уже связаны против текущего набора аргументов. Так в нашем примере мы бы сделаем тип совпадение на основе 1, 2 и время выполнения Тип d. Если у нас есть хит кэш, Затем мы возвращаем кэшированный результат. Если У нас нет кэша удара, то DLR проверяет, если приемник idynamicobject. Эти парни по существу объекты, которые знают, как позаботься об их собственном обязательном, таким Как объекты COM IDSPatch, реальные динамические такие предметы, как Ruby или Python, или какой-то объект .NET, который реализует интерфейс idynamicobject. Если это любой из них, то DLR звонит в IDO и просит его связать действие.

Обратите внимание, что результат вызова IDO, чтобы связать это выражение дерева, которое представляет результат связывания. Если это не IDO, то DLR звонит в связующее языку (в нашем корпус, связующее время выполнения C #), чтобы связать операция. Связующее время выполнения C # свяжут действие и вернется дерево выражения, представляющее результат связывания. Один раз шаг 2 или 3 произошло, в результате дерево выражения сливается в механизм кэширования так, чтобы любой Последующие вызовы могут работать против кэш вместо того, чтобы быть отскок.

Однако то, что Сэм не упоминает, что именно то, что такое политика мисс кэш. Существует два основных политики миссива в кэш-мисс: (1) Запустить пропустить кэш-память, когда типы аргументов изменяются, (2) срабатывает в кэш-памяти, когда аргументосменные идентичности меняются.

Очевидно, что первый гораздо больше исполнен; Разработка, когда мы можем кэшировать на основе исключительно на типе, сложно. Подробный эффект того, как все, что логические работы будут предпринимать довольно долгое время; Надеюсь, я или Крис или Сэм сделали сообщение в блоге на нем на днях.

3
ответ дан 4 December 2019 в 03:16
поделиться

Хорошо, вместо того, чтобы ждать ответа, я запустил Visual Studio 2010 beta 2, и эта тестовая программа работает хорошо:

class Foo
{
    public string foo = "Foo!";
}
class Bar
{
    public int bar = 42;
}

class Program
{
    static void Main(string[] args)
    {
        var test = new List<dynamic>();
        test.Add(new Foo());
        test.Add(new Bar());

        Console.WriteLine(test[0].foo.Substring(0,3));
        Console.WriteLine(test[1].bar.ToString("000"));

        Console.ReadKey(true);
    }
}

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

-121--3186068-

У вас есть различные причины для все еще большого размера git репо после git gc , так как он не удаляет все свободные объекты .

Я подробно описываю эти причины в « уменьшите размер репозитория git »

Но одним из трюков для проверки в вашем случае было бы клонировать ваше «очищенное» репо Git и посмотреть, имеет ли клон соответствующий размер.

(«» очищенное «репо» быть то, где вы применили фильтр-ветвь , а затем gc и обрезку )

-121--844311-

Вы можете думать о динамике как просто синтаксическом сахаре для записи всех вызовов метода с помощью Reflection and MethodInfo.Invoke () - под капотом он работает не совсем так, но вы можете думать о том, что он работает таким образом, со всеми «вызывающими 1000 методов/сек через dynamic = > убитый perf» соображений, которые идут с ним.

1
ответ дан 4 December 2019 в 03:16
поделиться

Список Список / , он может просто увидеть объект . Динамика в основном в глазах смотрящего - то есть COLLING код; Под капотом это «объект плюс немного сахара». Так что вы не должны видеть никаких проблем здесь.

Доказательство:

    static void Main()
    {
        Console.WriteLine(IsObject<int>()); // false
        Console.WriteLine(IsObject<object>()); // true
        Console.WriteLine(IsObject<dynamic>()); // true
        Console.WriteLine(IsObject<string>()); // false
    }
    static bool IsObject<T>()
    {
        return typeof(T) == typeof(object);
    }
1
ответ дан 4 December 2019 в 03:16
поделиться

Проблема заключается в том, что требуется связать некоторые данные с типами, а не с экземплярами типов. Я не уверен, что в C # есть правильный способ сделать это, но одна из возможностей - использование статического словаря < Type, последовательность [] > на BaseRecord . Ниже приведен пример, который можно устранить, добавив некоторые общие статические членов на BaseRecord для инициализации/доступа к именам записей (и добавления проверки ошибок...):

using System;
using System.Collections.Generic;

namespace Records
{
    public class BaseRecord
    {
        public bool isDirty;
        public object[] itemArray;

        public static Dictionary<Type, string[]> columnNames = new Dictionary<Type, string[]>();
    }

    public class PeopleRec : BaseRecord
    {
        static PeopleRec()
        {
            string[] names = new string[2];
            names[0] = "FIRST_NAME";
            names[1] = "LAST_NAME";
            BaseRecord.columnNames[typeof(PeopleRec)] = names;
        }
    }

    public class DoWork<T> where T : BaseRecord
    {
        public void DisplayColumnNames()
        {
            foreach (string s in BaseRecord.columnNames[typeof(T)])
                Console.WriteLine("{0}", s);
        }

        public void DisplayItem(T t)
        {
            for (int i = 0; i < t.itemArray.Length; i++)
            {
                Console.WriteLine("{0}: {1}", BaseRecord.columnNames[typeof(T)][i], t.itemArray[i]);
            }
        }
    }

    class Program
    {
        public static void Main()
        {
            PeopleRec p = new PeopleRec
            {
                itemArray = new object[] { "Joe", "Random" }
            };

            DoWork<PeopleRec> w = new DoWork<PeopleRec>();
            w.DisplayColumnNames();
            w.DisplayItem(p);
        }
    }
}
-121--4460238-

$ div- > get _ parent _ node () ;//К сожалению, такой функции нет.

Обратите внимание, что для этого можно расширить SimpleXML. Например:

class my_xml extends SimpleXMLElement
{
    public function get_parent_node()
    {
        return current($this->xpath('parent::*'));
    }
}

Теперь все, что нужно сделать, это изменить код, используемый для создания SimpleXMLElement в первую очередь:

$foo = new SimpleXMLElement('<foo/>');
// becomes
$foo = new my_xml('<foo/>');

$foo = simplexml_load_string('<foo/>');
// becomes
$foo = simplexml_load_string('<foo/>', 'my_xml');

$foo = simplexml_load_file('foo.xml');
// becomes
$foo = simplexml_load_file('foo.xml', 'my_xml');

Лучше всего то, что SimpleXML автоматически и прозрачно возвращает объекты my _ xml для этого документа, так что не нужно ничего менять, что делает метод get _ parent _ node () цепным:

// returns $grandchild's parent's parent
$grandchild->get_parent_node()->get_parent_node();
-121--2121740-

Хорошо, вместо того, чтобы ждать ответа, я запустил Visual Studio 2010 бета-версию 2, и эта тестовая программа работает нормально:

class Foo
{
    public string foo = "Foo!";
}
class Bar
{
    public int bar = 42;
}

class Program
{
    static void Main(string[] args)
    {
        var test = new List<dynamic>();
        test.Add(new Foo());
        test.Add(new Bar());

        Console.WriteLine(test[0].foo.Substring(0,3));
        Console.WriteLine(test[1].bar.ToString("000"));

        Console.ReadKey(true);
    }
}

Я хотел убедиться, что я не только проверял свойства с разными именами, но и имел разные типы и что я использовал в каждом типе несовместимые друг с другом функции. Это , кажется, предполагает, что если что-либо кэшировано, среда выполнения достаточно умна, чтобы знать, когда использовать кэш, а когда нет. Я все еще хотел бы услышать, знает ли кто-нибудь краевое дело, где это может не держаться, или более авторитетный комментарий о том, почему это произойдет.

1
ответ дан 4 December 2019 в 03:16
поделиться
Другие вопросы по тегам:

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