문제

그만큼 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의 실제 사용 사례를 보여주는 블로그 게시물을 썼습니다. 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;

       if (e != null)
       {
           e(d, new EventArgs());
       }

       // We could also fire it with...
       //      d.MyEvent(d, new EventArgs());

       // ...if we knew for sure that the event is non-null.
   }

   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);
   }
}

다른 팁

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

사전 항목보다는 DLR 속성을 기대하는 동적 언어와의 상호 운용성도 일부 시나리오에서도 고려할 수 있습니다.

나에게 진정한 이점은 XAML의 완전히 쉬운 데이터 바인딩입니다.

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

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

다른 언어와 상호 로프 DLR 내가 생각할 수있는 #1 이유입니다. 당신은 그들을 전달할 수 없습니다 Dictionary<string, object> 그렇지 않기 때문에 IDynamicMetaObjectProvider. 또 다른 추가 혜택은 IT가 구현된다는 것입니다 INotifyPropertyChanged 이는 WPF의 데이터 바인딩 세계에서 무엇을 넘어서 이점을 추가했음을 의미합니다. Dictionary<K,V> 당신에게 제공 할 수 있습니다.

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

사전을 사용하여 더 이상 "위조"속성을 추가하지 않기 때문에 구문이 이익을 얻을 것이라고 생각합니다.

그 말, 그리고 내가 생각하는 역동적 인 언어와 상호 로프.

그것은 위대한 예입니다 MSDN 기사 사용에 대해 ExpandoObject 들어오는 구조화 된 데이터 (예 : XML, JSON)를위한 동적 임시 유형을 생성합니다.

우리는 또한 대의원을 할당 할 수 있습니다 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);

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

이것이 편리한 경우가 있습니다. 예를 들어 모듈 식 쉘에 사용하겠습니다. 각 모듈은 자체 구성 대화 상자가 설정에 따라 데이터를 정의합니다. ExpandooBject를 데이터 콘텍스트로 제공하고 구성 저장소에 값을 저장합니다. 이런 식으로 구성 대화 상자 작성자는 값에 바인딩해야하며 자동으로 생성되고 저장됩니다. (물론 이러한 설정을 사용하기 위해 모듈에 제공됨)

사전보다 사용하기가 더 쉽습니다. 그러나 모든 사람은 내부적으로 사전 일 뿐이라는 것을 알고 있어야합니다.

그것은 Linq 단지 구문 설탕과 같지만 때로는 상황이 더 쉬워집니다.

따라서 질문에 직접 대답하기 위해 : 글을 쓰는 것이 더 쉽고 읽기가 더 쉽습니다. 그러나 기술적으로 그것은 본질적으로 a Dictionary<string,object> (값을 나열하기 위해 하나로 캐스팅 할 수도 있습니다).

var obj = new Dictionary<string, object>;
...
Console.WriteLine(obj["MyString"]);

내 생각에는 모든 것이 ToString()을 가지고 있기 때문에 작동한다고 생각합니다. 그렇지 않으면 그것이 있었던 유형을 알고 '객체'를 해당 유형으로 캐스팅해야 합니다.


이들 중 일부는 다른 것보다 더 자주 유용하므로 철저하게 설명하려고 노력하고 있습니다.

  1. 보다 직접적인 점 표기법을 사용하여 컬렉션(이 경우 사실상 "사전")에 액세스하는 것이 훨씬 더 자연스러울 수 있습니다.

  2. 이것이 정말 멋진 Tuple로 사용될 수 있을 것 같습니다.여전히 멤버를 "Item1", "Item2" 등으로 부를 수 있습니다.하지만 이제는 그럴 필요가 없습니다. Tuple과 달리 변경도 가능합니다.이는 Intellisense 지원이 부족하다는 큰 단점이 있습니다.

  3. "멤버 이름을 문자열로" 사용하는 것이 불편할 수 있습니다. 사전의 느낌과 마찬가지로 "문자열 실행"과 너무 비슷하다고 느낄 수도 있습니다. 명명 규칙이 코드화되고 형태소 및 작업을 처리하게 될 수도 있습니다. 코드가 멤버 사용 방법을 이해하려고 할 때 음절 :-P

  4. ExpandoObject 자체에 값을 할당할 수 있습니까? 아니면 해당 멤버에만 할당할 수 있습니까?동적/동적[]과 비교하고 대조하여 필요에 가장 적합한 것을 사용하세요.

  5. 나는 동적/동적[]이 foreach 루프에서 작동하지 않는다고 생각합니다. var를 사용해야 하지만 ExpandoObject를 사용할 수도 있습니다.

  6. 최소한 키워드와 유사하기 때문에 클래스의 데이터 멤버로 Dynamic을 사용할 수 없습니다. ExpandoObject를 사용하면 가능하기를 바랍니다.

  7. 나는 이것이 ExpandoObject라고 기대하며, 동적 항목이 많이 사용되는 유형을 기반으로 구별하는 코드를 사용하여 매우 일반적인 항목을 구분하는 데 유용할 수 있다고 기대합니다.


한 번에 여러 수준을 드릴다운할 수 있다면 좋을 것입니다.

var e = new ExpandoObject();
e.position.x = 5;
etc...

이는 최선의 예는 아닙니다. 자신의 프로젝트에 적절하게 우아하게 사용하는 것을 상상해보세요.

이들 중 일부를 코드로 작성하고 결과를 Intellisense로 푸시할 수 없다는 것은 유감스러운 일입니다.그래도 이것이 어떻게 작동할지 잘 모르겠습니다.

멤버들과 마찬가지로 가치도 가질 수 있다면 좋을 것 같아요.

var fifteen = new ExpandoObject();
fifteen = 15;
fifteen.tens = 1;
fifteen.units = 5;
fifteen.ToString() = "fifteen";
etc...

Valuetuples 후에는 ExpandooBject 클래스의 사용은 무엇입니까? expandoobject가있는이 6 줄 코드 :

dynamic T = new ExpandoObject();
T.x = 1;
T.y = 2;
T.z = new ExpandoObject();
T.z.a = 3;
T.b= 4;

튜플과 함께 한 줄로 쓸 수 있습니다.

var T = (x: 1, y: 2, z: (a: 3, b: 4));

튜플 구문 외에도 강력한 유형의 추론과 intlisense 지원이 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top