ExpandoObject এর আসল উপকারিতা কী কী?


587

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 ব্যবহার করে শুধু একটি অবাধ অভিধান টাইপ, আপনি একটি টাইপ যে রানটাইম এ নির্ধারণ করা যাচ্ছে ব্যবহার করছেন সুস্পষ্ট না হওয়া ছাড়া ব্যবহার করে অর্জন করা হয়।

উত্তর:


689

যেহেতু আপনি যে এমএসডিএন নিবন্ধটি লিখেছেন সে সম্পর্কে আমি লিখলাম, আমার ধারণা এই উত্তরটি আমাকে দিতে হবে।

প্রথমত, আমি এই প্রশ্নটি আগে থেকেই অনুমান করেছিলাম এবং সে কারণেই আমি একটি ব্লগ পোস্ট লিখেছিলাম যা ExpandoObject এর জন্য কম-বেশি বাস্তব ব্যবহারের কেস দেখায়: সি # 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


53
মজাদার. তথ্য পুনরায়: ইভেন্টের জন্য ধন্যবাদ। এটা আমার জন্য নতুন ছিল।
রিড কোপসি

16
@ আলেকজান্দ্রা রুসিনা, আপনি কীভাবে বলবেন যে এটি কোনও ঘটনা d.MyEvent = null;, বা তা হয় না?
শিমি ওয়েটজ্যান্ডলার

20
হয়তো আমি কিছু মিস করছি, তবে এটি কোনও ইভেন্ট নয় - এটি প্রতিনিধি ধরণের একটি সাধারণ সম্পত্তি।
সের্গেই বেরেজোভস্কি

7
প্রথম ব্লকটি বেনামে টাইপ করে লেখা যেতে পারে: var expando = new { Address = new { State = "WA" } }; Console.WriteLine(expando.Address.State);আমি এটি আরও পাঠযোগ্য তবে ymmv find এবং এটি স্ট্যাটিকালি টাইপ করা হয়েছে, এটি এই প্রসঙ্গে আরও কার্যকর।
নওফাল

13
@ নওফাল ঠিক না - একটি বেনামী একটি এক্সপেন্ডোর থেকে আলাদা। আপনি একটি বেনামি প্রকার তৈরি করছেন, যা এরপরে স্বেচ্ছাচারী বৈশিষ্ট্য যুক্ত করতে পারে না।
ডাঃ ব্লোহার্ড

75

একটি সুবিধা বন্ডিং দৃশ্যের জন্য। ডেটা গ্রিড এবং সম্পত্তি গ্রিডগুলি টাইপডেস্ক্রিপ্টর সিস্টেমের মাধ্যমে গতিশীল বৈশিষ্ট্যগুলি বেছে নেবে। তদ্ব্যতীত, ডাব্লুপিএফ ডেটা বাইন্ডিং গতিশীল বৈশিষ্ট্যগুলি বুঝতে পারে, তাই ডাব্লুপিএফ নিয়ন্ত্রণগুলি একটি এক্সপান্ডোঅবজেক্টকে একটি অভিধানের চেয়ে আরও সহজে সীমাবদ্ধ করতে পারে।

গতিশীল ভাষার সাথে ইন্টারঅ্যাপেরিবিলিটি, যা অভিধান এন্ট্রিগুলির পরিবর্তে ডিএলআর বৈশিষ্ট্যগুলির প্রত্যাশা করবে, কিছু পরিস্থিতিতে এটি বিবেচনাও হতে পারে।


6
দেখে মনে হচ্ছে গতিশীল বস্তুগুলিতে ডেটাবাইন্ডিং নষ্ট হয়ে গেছে । রিপোর্টিং ব্যবহারকারী আইজেনবার্গেফেক্ট এখানে এসও এবং ক্যালিবার্ন.মিক্রোর সমন্বয়কারীতে রয়েছে। @ আলেকান্দ্রা রুসিনা আপনি বাগের অবস্থা এবং "ঠিক করতে পারবেন না" স্থিতির বিষয়ে মন্তব্য করতে পারেন
21:04

2
কৌতূহলীদের জন্য, আমি বর্তমানে ডাব্লুপিএফ List<dynamic>IEnumerable<dynamic>
গ্রাহাম বাস

47

আমার জন্য আসল উপকারটি এক্সএএমএল থেকে সম্পূর্ণ অনায়াসে ডেটা বাধ্যতামূলক:

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

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

28

এর ভিত্তিতে প্রতিষ্ঠিত অন্যান্য ভাষার সাথে ইন্টারপ করা DLRহ'ল # 1 কারণ আমি ভাবতে পারি। Dictionary<string, object>এটি একটি হিসাবে আপনি তাদের পাস করতে পারবেন না IDynamicMetaObjectProvider। আরেকটি যুক্ত সুবিধা হ'ল এটি প্রয়োগ করে INotifyPropertyChangedযার অর্থ ডাব্লুপিএফের ডেটাবাইন্ডিং বিশ্বে এটি Dictionary<K,V>আপনাকে যা সরবরাহ করতে পারে তার থেকেও বেশি সুবিধা যুক্ত করেছে ।


19

এটি সব প্রোগ্রামার সুবিধার জন্য। আমি এই অবজেক্টটি দিয়ে দ্রুত এবং নোংরা প্রোগ্রাম লেখার কল্পনা করতে পারি।


9
@J। হেন্ডরিক্স, ভুলে যাবেন না যে তিনি "নোংরা "ও বলেছিলেন। ইন্টেলিজেন্স এর খারাপ দিক রয়েছে, তবে এটি ডিবাগিং এবং বাগ-ক্যাচিংকে সহজ করে তোলে। আমি অদ্ভুত (এবং সর্বদা বিরল) কেস না হলে আমি ব্যক্তিগতভাবে গতিশীল ধরণের চেয়ে স্থির পছন্দ করি।
ফিল

সুবিধার জন্য +1। তবে আমি খুঁজে পাই বেনাম প্রকারগুলি একটি সাধারণ সম্পত্তি ব্যাগ হিসাবে সমান সুবিধাজনক এবং এর স্থির-নেছের জন্য আরও ভাল better
নওফাল

1
আমি এটি প্রোডাকশন কোডে ব্যবহার করতে চাই না, তবে এটি পরীক্ষার কোডে খুব সুবিধাজনক এবং এটিকে খুব সুন্দর দেখাচ্ছে look
টোবিয়াস

14

আমি মনে করি এটির সিন্ট্যাক্টিক সুবিধা হবে, কারণ আপনি অভিধানটি ব্যবহার করে আর গতিশীলভাবে যুক্ত বৈশিষ্ট্য যুক্ত করবেন না।

এটি, এবং গতিশীল ভাষাগুলির সাথে আন্তঃআপনার আমি ভাবি।


11

এটি 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);

সুতরাং এটি আমাদের রানটাইমে গতিশীল অবজেক্টে কিছু যুক্তি সংযোজন করতে দেয়। অতএব, ল্যাম্বডা এক্সপ্রেশন, ক্লোজার, ডায়নামিক কীওয়ার্ড এবং ডাইনামিকঅবজেক্ট শ্রেণীর সাথে একত্রে আমরা আমাদের সি # কোডের মধ্যে ফাংশনাল প্রোগ্রামিংয়ের কিছু উপাদান প্রবর্তন করতে পারি, যা আমরা জাভাস্ক্রিপ্ট বা পিএইচপি এর মতো গতিশীল ভাষা থেকে জানি।


4

কিছু ঘটনা আছে যেখানে এটি কার্যকর। আমি উদাহরণস্বরূপ এটি একটি Modulariised শেল জন্য ব্যবহার করব। প্রতিটি মডিউল এটির সেটিংসে নিজস্ব কনফিগারেশন ডায়ালগ ডেটাবাইন্ড সংজ্ঞায়িত করে। আমি এটি একটি ডেটাঅন্টেক্সট হিসাবে একটি ExpandoObject সরবরাহ করি এবং আমার কনফিগারেশন স্টোরেজে মানগুলি সংরক্ষণ করি save এইভাবে কনফিগারেশন ডায়ালগ লেখককে কেবল একটি মানকে বাঁধতে হয় এবং এটি স্বয়ংক্রিয়ভাবে তৈরি এবং সংরক্ষণ করা হয়। (এবং এই সেটিংস অবশ্যই ব্যবহারের জন্য মডিউলটি সরবরাহ করা হয়েছে)

অভিধানের তুলনায় এটি ব্যবহার করা সহজ। তবে প্রত্যেকেরই সচেতন হওয়া উচিত যে অভ্যন্তরীণভাবে এটি কেবল একটি অভিধান।

এটি লিনকুই যেমন সিনট্যাকটিক চিনির মতো তবে এটি কখনও কখনও জিনিসগুলিকে সহজ করে তোলে।

সুতরাং আপনার প্রশ্নের সরাসরি উত্তর দিতে: এটি লেখা সহজ এবং পড়া সহজ easier তবে প্রযুক্তিগতভাবে এটি মূলত একটি Dictionary<string,object>(মানগুলি তালিকার জন্য আপনি এটি একটিতেও দিতে পারেন)।


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

আমি মনে করি যে কেবলমাত্র কাজ করে কারণ সমস্ত কিছুর একটি টুস্ট্রিং () রয়েছে, অন্যথায় আপনি এটি যে ধরণের তা জানতেন এবং সেই ধরণের 'অবজেক্ট' নিক্ষেপ করতে পারবেন।


এর মধ্যে কয়েকটি অন্যের চেয়ে বেশি বেশি দরকারী, আমি পুরোপুরি চেষ্টা করার চেষ্টা করছি।

  1. কোনও সংগ্রহের অ্যাক্সেস করা আরও প্রাকৃতিক হতে পারে, এই ক্ষেত্রে আরও সরাসরি ডট স্বরলিপি ব্যবহার করে কার্যকরভাবে একটি "অভিধান" কী।

  2. দেখে মনে হচ্ছে এটি সত্যিই সুন্দর টিপল হিসাবে ব্যবহার করা যেতে পারে। আপনি এখনও আপনার সদস্যদের "আইটেম 1", "আইটেম 2" ইত্যাদি কল করতে পারেন ... তবে এখন আপনার দরকার নেই, এটি টিউপলের মতো নয়, এটিও পরিবর্তনযোগ্য। এটিতে ইন্টেলিজেন্স সমর্থনের অভাবের বিশাল ক্ষতি রয়েছে।

  3. আপনি "সদস্যের নামগুলি স্ট্রিং হিসাবে" নিয়ে অস্বস্তি বোধ করতে পারেন, অভিধানের সাথে যেমন অনুভূতি রয়েছে তেমনই আপনিও এটি "এক্সিকিউটিং স্ট্রিং" এর মতো বলে মনে করতে পারেন, এবং এটি কনভেনশনগুলির নামকরণে কোডিং হয়ে যেতে পারে এবং মরফিমগুলির সাথে কাজ করার ক্ষেত্রে আচরণ করতে পারে এবং কোডটি সদস্যদের কীভাবে ব্যবহার করতে হয় তা বোঝার চেষ্টা করা হয়: সি

  4. আপনি নিজেই কোনও এক্সপেন্ডোঅবজেক্ট বা কেবল এর সদস্যদের কোনও মূল্য নির্ধারণ করতে পারেন? গতিশীল / গতিশীল [] এর সাথে তুলনা করুন এবং এর বিপরীতে, আপনার প্রয়োজনগুলির মধ্যে যেটি সবচেয়ে ভাল স্যুট ব্যবহার করুন।

  5. আমার মনে হয় না ডাইনামিক / ডায়নামিক [] একটি অগ্রভাগ লুপে কাজ করে, আপনার বিভিন্ন ব্যবহার করতে হবে তবে সম্ভবত আপনি ExpandoObject ব্যবহার করতে পারেন।

  6. আপনি কোনও ক্লাসে ডেটা সদস্য হিসাবে ডায়নামিক ব্যবহার করতে পারবেন না, কারণ এটি কমপক্ষে একটি কীওয়ার্ডের মতো সাজান, আশা করি আপনি ExpandoObject এর মাধ্যমে করতে পারেন।

  7. আমি আশা করি এটি "একটি" একটি এক্সপেন্ডোঅবজেক্ট, খুব জেনেরিক জিনিসকে আলাদা করে লেবেল করতে কার্যকর হতে পারে, কোড সহ এমন ধরণের কোডের ভিত্তিতে পার্থক্য রয়েছে যেখানে প্রচুর গতিশীল স্টাফ ব্যবহৃত হচ্ছে।


আপনি একবারে একাধিক স্তর ড্রিল করতে পারলে সুন্দর হন।

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

এটি সর্বোত্তম সম্ভাব্য উদাহরণ নয়, আপনার নিজের প্রকল্পগুলিতে মার্জিত ব্যবহারগুলি কল্পনা করুন appropriate

এটি লজ্জাজনক যে আপনার কোডগুলি এর মধ্যে কিছু তৈরি করতে না পারে এবং ফলাফলগুলিকে ইন্টেলিসেন্সে ঠেলাতে পারে না। যদিও এটি কাজ করবে আমি নিশ্চিত নই।

সদস্যদের পাশাপাশি তাদের যদি একটি মান থাকতে পারে তবে সুন্দর হন।

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

-3

ভ্যালুটুপলসের পরে এক্সপেন্ডোঅবজেক্ট ক্লাসের ব্যবহার কী? 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));

টুপল সিনট্যাক্স ছাড়াও আপনার শক্তিশালী টাইপ অনুমিতি এবং অন্তর্নিহিত সমর্থন রয়েছে


1
আপনার উদাহরণগুলি এই অর্থে অভিন্ন নয় যে মান টিউপল সহ, আপনি টিসি = 5 লিখতে পারবেন না; সমাপ্তির পরে টি সংজ্ঞায়িত করুন ExpandoObject দিয়ে আপনি এটি করতে পারেন কারণ এটি গতিশীল। মান টিউপল সহ আপনার উদাহরণ বেনামি ধরণের ঘোষণার সাথে খুব অভিন্ন। যেমন: var T2 = new {x = 1, y = 2, z = new {a = 3, b = 4}};
LxL

আমাকে টিসি = 5 লেখার দরকার নেই কেন? .NET- এ ডিফেন্ড না হওয়া COM অবজেক্টগুলির সাথে ডিল করার সময় ExpandoObject কেবলমাত্র দরকারী। অন্যথায়, আমি অবশ্যই এই ExpandoObject ব্যবহার করি না, কারণ এটি নকশার সময় এবং রানটাইম উভয়ই নোংরা এবং বগি।
ইঞ্জি। এমহ্যামদি

1
আপনার প্রথমে z কীভাবে নির্ধারিত হবে (a: 3, b: 4) এবং তারপরে আপনি z এর অতিরিক্ত সি সম্পত্তি পেতে চান? আপনি মান টিপল দিয়ে এটি করতে পারেন?
LxL

সুতরাং আমার বক্তব্যটি হ'ল আপনি এক্সপেন্ডোঅবজেক্টকে মান টিউপলের সাথে তুলনা করতে পারবেন না কারণ তারা বিভিন্ন উদ্দেশ্যে ডিজাইন করা হয়েছে। আপনার উপায়ের সাথে তুলনা করে আপনি যে কার্যকারিতাটি ExpandoObject এর জন্য ডিজাইন করেছেন তা বাতিল করে দিয়েছিলেন, যা গতিশীল কাঠামো।
LxL
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.