IT

ExpandoObject, DynamicObject 및 dynamic의 차이점

lottoking 2020. 6. 2. 21:14
반응형

ExpandoObject, DynamicObject 및 dynamic의 차이점


무슨 사이의 차이점은 System.Dynamic.ExpandoObject, System.Dynamic.DynamicObject그리고 dynamic?

어떤 상황에서 이러한 유형을 사용합니까?


dynamic키워드는 런타임에 바인딩해야 변수를 선언하는 데 사용됩니다.
실제 또는 상상 유형에 대해 늦은 바인딩을 사용하려면 dynamic키워드 를 사용 하고 나머지는 컴파일러에서 수행합니다.

dynamic키워드를 사용하여 일반 인스턴스와 상호 작용할 때 DLR 은 인스턴스의 일반 메서드에 대한 지연 호출을 수행합니다.

IDynamicMetaObjectProvider인터페이스는 클래스가 런타임에 바인딩 된 행동을 제어 할 수 있습니다. 키워드를
사용하여 구현 dynamic과 상호 작용 IDynamicMetaObjectProvider하면 DLR이 IDynamicMetaObjectProvider메소드를 호출 하고 객체 자체가 수행 할 작업을 결정합니다.

ExpandoObjectDynamicObject클래스의 구현입니다 IDynamicMetaObjectProvider.

ExpandoObject인스턴스에 멤버를 추가하고 dynamic동맹을 사용할 수있는 간단한 클래스입니다 .
DynamicObject사용자 정의 된 동작을 쉽게 제공하기 위해 상속 될 수있는 고급 구현입니다.


나는이 질문에 더 명확한 답을 제공하여 동적 ExpandoObject의 차이점이 무엇인지 명확하게 설명하려고 노력할 것이다 DynamicObject.

매우 빨리 dynamic키워드입니다. 그 자체로는 유형이 아닙니다. 컴파일러가 디자인 타임에 정적 유형 검사를 무시하고 대신 런타임에 후기 바인딩을 사용하도록 지시하는 키워드입니다. 따라서 우리는 dynamic이 답변의 나머지 부분에서 많은 시간을 할애하지 않을 것 입니다.

ExpandoObject그리고 DynamicObject실제로 유형입니다. SURFACE에서는 서로 매우 유사하게 보입니다. 두 클래스 모두 구현 IDynamicMetaObjectProvider합니다. 그러나 더 깊이 파고 들면 전혀 비슷하지 않다는 것을 알 수 있습니다.

DynamicObject는 IDynamicMetaObjectProvider순전히 부분적인 구현으로 개발자가 사용자 지정 기본 저장소 및 검색 동작으로 동적 디스패치를 ​​지원하는 동적 사용자 지정 유형을 구현하여 동적 디스패치 작업을 시작하기위한 출발점입니다.

  1. DynamicObject는 직접 생성 할 수 없습니다.
  2. 개발자로서 귀하가 사용할 수 있도록 DynamicObject를 확장해야합니다.
  3. DynamicObject를 확장하면 이제 동적 디스패치가 런타임시 기본 데이터 표시에 내부적으로 저장된 데이터로 해석되는 방법에 관한 CUSTOM 동작을 제공 할 수 있습니다.
  4. ExpandoObject는 기본 데이터를 사전 등에 저장합니다. DynamicObject를 구현하면 원하는 위치에 데이터를 저장할 수 있습니다. (예 : 발송시 데이터를 가져오고 설정하는 방법은 전적으로 귀하에게 달려 있습니다).

요컨대, DLR과 함께 사용할 수 있고 원하는 CUSTOM 동작과 함께 사용할 수있는 OWN 형식을 만들려면 DynamicObject를 사용하십시오.

예 : 존재하지 않는 멤버 (예 : 런타임에 추가되지 않은 멤버)에 대해 가져 오기를 시도 할 때마다 사용자 정의 기본값을 리턴하는 동적 유형을 원한다고 가정하십시오. 그리고 그 기본값은 "죄송합니다.이 병에는 쿠키가 없습니다!"라고 말합니다. 이와 같이 동작하는 동적 객체를 원하면 필드를 찾을 수 없을 때 발생하는 동작을 제어해야합니다. ExpandoObject를 사용하면이 작업을 수행 할 수 없습니다. 따라서 고유 한 동적 멤버 확인 (디스패치) 동작으로 고유 한 유형을 작성하고 기성 빌드 대신이를 사용해야합니다 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;
    }
}

Now, we could use this imaginary class we just created as a dynamic type that has a very custom behavior if the field doesn't exist.

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 is a FULL implementation of IDynamicMetaObjectProvider, where the .NET Framework team has made all of these decisions for you. This is useful if you don't need any custom behavior, and you feel that ExpandoObject works good enough for you (90% of the time, ExpandoObject is good enough). So for example, see the following, and that for ExpandoObject, the designers chose to throw an exception if the dynamic member does not exist.

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) { ... }

So to summarize, ExpandoObject is simply one pre-chosen way to extend DynamicObject with certain dynamic dispatch behaviors that will probably work for you, but may not depending on your particular needs.

Whereas, DyanmicObject is a helper BaseType that makes implementing your own types with unique dynamic behaviors simple and easy.

A useful tutorial on which much of the example source above is based.


According to the C# language specification dynamic is a type declaration. I.e. dynamic x means the variable x has the type dynamic.

DynamicObject is a type that makes it easy to implement IDynamicMetaObjectProvider and thus override specific binding behavior for the type.

ExpandoObject is a type that acts like a property bag. I.e. you can add properties, methods and so forth to dynamic instances of this type at runtime.


The above example of DynamicObject does not tell the difference clearly, because it's basically implementing the functionality which is already provided by ExpandoObject.

In the two links mentioned below, it is very clear that with the help of DynamicObject, it is possible to preserve/change the actual type (XElement in the example used in below links) and better control on properties and methods.

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

https://blogs.msdn.microsoft.com/csharpfaq/2009/10/19/dynamic-in-c-4-0-creating-wrappers-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;    
        }    
    }    
}

참고URL : https://stackoverflow.com/questions/3565481/differences-between-expandoobject-dynamicobject-and-dynamic

반응형