[C#] ExpandoObject의 진정한 이점은 무엇입니까?

ExpandoObject의 클래스는 런타임시 객체에 .NET 4 임의로 설정 속성 수에 추가.

Dictionary<string, object>, 또는 심지어 해시 테이블 을 사용하는 것보다 이점이 있습니까? 내가 알 수있는 한, 이것은 약간 더 간결한 구문으로 액세스 할 수있는 해시 테이블에 지나지 않습니다.

예를 들어, 왜 이럴까요 :

dynamic obj = new ExpandoObject();
obj.MyInt = 3;
obj.MyString = "Foo";
Console.WriteLine(obj.MyString);

다음보다 훨씬 좋거나 실질적으로 다릅니다.

var obj = new Dictionary<string, object>();
obj["MyInt"] = 3;
obj["MyString"] = "Foo";

Console.WriteLine(obj["MyString"]);

런타임에 결정되는 유형을 사용하고 있는지 확실하지 않는 한 임의의 사전 유형을 사용하는 대신 ExpandoObject를 사용하면 얻을 수있는 실제 이점은 무엇입니까?



답변

언급 한 MSDN 기사를 작성 했으므로이 기사에 대답해야한다고 생각합니다.

먼저이 질문을 예상했기 때문에 ExpandoObject : Dynamic in C # 4.0 : ExpandoObject 소개에 대한 실제 사용 사례를 보여주는 블로그 게시물을 작성했습니다 .

곧 ExpandoObject를 사용하면 복잡한 계층 적 개체를 만들 수 있습니다. 예를 들어, 사전 내에 사전이 있다고 가정하십시오.

Dictionary<String, object> dict = new Dictionary<string, object>();
Dictionary<String, object> address = new Dictionary<string,object>();
dict["Address"] = address;
address["State"] = "WA";
Console.WriteLine(((Dictionary<string,object>)dict["Address"])["State"]);

계층이 깊을수록, 추악한 것이 코드입니다. ExpandoObject를 사용하면 우아하고 읽을 수 있습니다.

dynamic expando = new ExpandoObject();
expando.Address = new ExpandoObject();
expando.Address.State = "WA";
Console.WriteLine(expando.Address.State);

둘째, 이미 지적했듯이 ExpandoObject는 INotifyPropertyChanged 인터페이스를 구현하여 사전보다 속성을 더 많이 제어 할 수 있습니다.

마지막으로 다음과 같이 ExpandoObject에 이벤트를 추가 할 수 있습니다.

class Program
{
   static void Main(string[] args)
   {
       dynamic d = new ExpandoObject();

       // Initialize the event to null (meaning no handlers)
       d.MyEvent = null;

       // Add some handlers
       d.MyEvent += new EventHandler(OnMyEvent);
       d.MyEvent += new EventHandler(OnMyEvent2);

       // Fire the event
       EventHandler e = d.MyEvent;

       e?.Invoke(d, new EventArgs());
   }

   static void OnMyEvent(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent fired by: {0}", sender);
   }

   static void OnMyEvent2(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent2 fired by: {0}", sender);
   }
}

또한 동적으로 이벤트 인수를 허용하는 데 방해가되는 것은 없습니다. 즉,을 사용하는 대신 핸들러의 두 번째 인수를 EventHandler사용 EventHandler<dynamic>하는을 사용할 수 있습니다 dynamic.


답변

하나의 장점은 바인딩 시나리오에 대한 것입니다. 데이터 그리드 및 속성 그리드는 TypeDescriptor 시스템을 통해 동적 속성을 선택합니다. 또한 WPF 데이터 바인딩은 동적 속성을 이해하므로 WPF 컨트롤은 사전보다 ExpandoObject에 더 쉽게 바인딩 할 수 있습니다.

일부 시나리오에서는 사전 항목이 아닌 DLR 속성이 필요한 동적 언어와의 상호 운용성이 고려 될 수도 있습니다.


답변

저에게있어 실질적인 이점은 XAML에서 완전히 손쉬운 데이터 바인딩입니다.

public dynamic SomeData { get; set; }

SomeData.WhatEver = "Yo Man!";

 <TextBlock Text="{Binding SomeData.WhatEver}" />


답변

다른 언어와의 상호 운용성에 대해 DLR생각할 수 있습니다. 당신은 그들에게 전달할 수 없습니다 Dictionary<string, object>그것이 아니다로 IDynamicMetaObjectProvider. 또 다른 이점은 INotifyPropertyChangedWPF의 데이터 바인딩 세계에서 구현할 수 있다는 것 외에 다른 이점도 제공한다는 Dictionary<K,V>것입니다.


답변

프로그래머 편의성에 관한 것입니다. 이 객체로 빠르고 더러운 프로그램을 작성하는 것을 상상할 수 있습니다.


답변

더 이상 사전을 사용하여 동적으로 추가 된 속성을 “가짜”로 만들지 않기 때문에 구문상의 이점이 있다고 생각합니다.

그것은 내가 생각하는 동적 언어와 상호 작용합니다.


답변

들어오는 구조화 된 데이터 (예 : XML, Json)에 대한 동적 임시 유형을 만들기 위해 ExpandoObject 를 사용하는 방법 에 대한 훌륭한 MSDN 기사 의 예입니다 .

ExpandoObject 의 동적 속성에 델리게이트를 할당 할 수도 있습니다.

dynamic person = new ExpandoObject();
person.FirstName = "Dino";
person.LastName = "Esposito";

person.GetFullName = (Func<String>)(() => {
  return String.Format("{0}, {1}",
    person.LastName, person.FirstName);
});

var name = person.GetFullName();
Console.WriteLine(name);

따라서 런타임에 일부 논리를 동적 객체에 주입 할 수 있습니다. 따라서 람다 식, 클로저, 동적 키워드 및 DynamicObject 클래스함께 함수 프로그래밍의 일부 요소를 C # 코드에 도입 할 수 있습니다. JavaScript 또는 PHP와 같이 동적 언어에서 알고 있습니다.