Различия между расширенным допуском, динамическими продуктами и динамическими

StackOverflow https://stackoverflow.com/questions/3565481

Вопрос

Каковы различия между System.Dynamic.ExpandoObject, System.Dynamic.DynamicObject а также dynamic?

В каких ситуациях вы используете эти типы?

Это было полезно?

Решение

То dynamic Ключевое слово используется для объявления переменных, которые должны быть поздно.
Если вы хотите использовать поздние привязки, для любого реального или воображаемого типа вы используете dynamic Ключевое слово и компилятор делает остальные.

Когда вы используете dynamic Ключевое слово для взаимодействия с нормальным экземпляром, Длр Выполняет поздние призывы к нормальным методам экземпляра.

То IDynamicMetaObjectProvider интерфейс Позволяет классу контролировать свое поздние поведение.
Когда вы используете dynamic ключевое слово для взаимодействия с IDynamicMetaObjectProvider Реализация, DLR вызывает IDynamicMetaObjectProvider Методы и сам объект решает, что делать.

То ExpandoObject а также DynamicObject Классы - это реализации IDynamicMetaObjectProvider.

ExpandoObject это простой класс, который позволяет добавлять членов в экземпляр и использовать их dynamicсоюзник.
DynamicObject является более продвинутой реализацией, которая может быть унаследована, чтобы легко обеспечить индивидуальное поведение.

Другие советы

Я постараюсь предоставить более четкий ответ на этот вопрос, четко объяснить, какие различия между динамическими, ExpandoObject а также DynamicObject.

Очень быстро, dynamic это ключевое слово. Это не тип se-se. Это ключевое слово, которое позволяет компилятору игнорировать статический тип проверки в режиме проектирования и вместо этого использовать поздние привязки во время выполнения. Так что мы не будем тратить много времени на dynamic В остальном этот ответ.

ExpandoObject а также DynamicObject действительно типы. На поверхности они выглядят очень похожи друг на друга. Оба класса реализуются IDynamicMetaObjectProvider. Отказ Тем не менее, копайте глубже, и вы найдете, что они совсем не похожи.

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

  1. DynamicObject не может быть сконструирован напрямую.
  2. Вы должны продлить динамическое значение для него, чтобы иметь для вас любое использование в качестве разработчика.
  3. Когда вы продвигаете DynamicObject, вы теперь можете предоставить пользовательское поведение в отношении того, как вы хотите, чтобы динамическая отправка разрешила в данные, сохраненные внутри, в вашем базовом представлении данных во время выполнения.
  4. Расширенные хранилищ основных данных в словаре и т. Д. Если вы реализуете DynamicObject, вы можете хранить данные везде, где и даже хотите. (например, как вы получаете и устанавливаете данные о диспетчере, полностью зависит от вас).

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

Пример: представьте, что вы хотите иметь динамический тип, который возвращает пользовательский по умолчанию всякий раз, когда получение предпринимается на участнике, который не существует (т.е. не был добавлен во время выполнения). И что по умолчанию скажет: «Извините, в этой банке нет файлов!». Если вы хотите динамический объект, который ведет себя так, вам нужно будет контролировать, что происходит, когда поле не найдено. Развертывать не позволит вам сделать это. Таким образом, вам нужно создать свой собственный тип с уникальным поведением динамического разрешения элементов (отправка) и использовать, а не готовый ExpandoObject.

Вы можете создать тип следующим образом: (Примечание, код ниже просто для иллюстрации и может не работать. Чтобы узнать о том, как правильно использовать DynamicObject, есть много статей и учебных пособий в другом месте.)

public class MyNoCookiesInTheJarDynamicObject : DynamicObject
{
    Dictionary<string, object> properties = new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (properties.ContainsKey(binder.Name))
        {
            result = properties[binder.Name];
            return true;
        }
        else
        {
            result = "I'm sorry, there are no cookies in this jar!"; //<-- THIS IS OUR 
            CUSTOM "NO COOKIES IN THE JAR" RESPONSE FROM OUR DYNAMIC TYPE WHEN AN UNKNOWN FIELD IS ACCESSED
            return false;
        }
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        properties[binder.Name] = value;
        return true;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        dynamic method = properties[binder.Name];
        result = method(args[0].ToString(), args[1].ToString());
        return true;
    }
}

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

dynamic d = new MyNoCookiesInTheJarDynamicObject();
var s = d.FieldThatDoesntExist;

//in our contrived example, the below should evaluate to true
Assert.IsTrue(s == "I'm sorry, there are no cookies in this jar!")

ExpandoObject является полной реализацией IDynamicMetaObjectProvider, где .NET Framework Team сделала все эти решения для вас. Это полезно, если вам не нужно какое-либо поведение, и вы чувствуете, что развертывание работает достаточно хорошо для вас (90% времени, ExpandoObject достаточно хорош). Так, например, см. Ниже, а для расширения, дизайнеры решили бросить исключение, если динамический элемент не существует.

dynamic d = new ExpandoObject();

/*
The ExpandoObject designers chose that this operation should result in an 
Exception. They did not have to make that choice, null could 
have been returned, for example; or the designers could've returned a "sorry no cookies in the jar" response like in our custom class. However, if you choose to use 
ExpandoObject, you have chosen to go with their particular implementation 
of DynamicObject behavior.
*/

try {
var s = d.FieldThatDoesntExist;
}
catch(RuntimeBinderException) { ... }

Так, чтобы обобщить, ExpandoObject просто один заранее выбранный способ расширить динамику Veach с определенным динамическим динамическим поведением, которые, вероятно, будут работать для вас, но не может в зависимости от ваших особых потребностей.

В то время как, DyanmicObject Это помощник BaseType, который делает реализацию ваших собственных типов с уникальным динамическим поведением простым и легким.

Полезный урок, на котором основан большая часть примера источника выше.

Согласно спецификации языка C # dynamic это типовое объявление. Т.е. dynamic x означает переменную x имеет тип dynamic.

DynamicObject это тип, который позволяет легко реализовать IDynamicMetaObjectProvider и таким образом переопределите конкретное поведение связывания для типа.

ExpandoObject это тип, который действует как сумка имущества. Т.е. вы можете добавлять свойства, методы и так далее для динамических экземпляров этого типа во время выполнения.

Вышеприведенный пример DynamicObject не рассказывает разницу ясно, потому что она в основном реализует функциональность, которая уже предоставляется ExpandoObject.

В двух ссылках, упомянутых ниже, очень ясно, что с помощью DynamicObject, можно сохранить / изменить фактический тип (XElement В примере, используемом при следующих ссылках) и лучшим контролем по свойствам и методам.

https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-te-expandoobject/

https://blogs.msdn.microsoft.com/csharpfaq/2009/10/19/dynamic-in-c-4-0-creating-wrapters-with-dynamicobject/

public class DynamicXMLNode : DynamicObject    
{    
    XElement node;

    public DynamicXMLNode(XElement node)    
    {    
        this.node = node;    
    }

    public DynamicXMLNode()    
    {    
    }

    public DynamicXMLNode(String name)    
    {    
        node = new XElement(name);    
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)    
    {    
        XElement setNode = node.Element(binder.Name);

        if (setNode != null)    
            setNode.SetValue(value);    
        else    
        {    
            if (value.GetType() == typeof(DynamicXMLNode))    
                node.Add(new XElement(binder.Name));    
            else    
                node.Add(new XElement(binder.Name, value));    
        }

        return true;    
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)    
    {    
        XElement getNode = node.Element(binder.Name);

        if (getNode != null)    
        {    
            result = new DynamicXMLNode(getNode);    
            return true;    
        }    
        else    
        {    
            result = null;    
            return false;    
        }    
    }    
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top