আমি কীভাবে গতিশীল অবজেক্টের সদস্যদের প্রতিফলিত করব?


131

.NET 4-এ ডায়নামিক কীওয়ার্ড সহ ঘোষিত কোনও বস্তু থেকে আমার বৈশিষ্ট্য এবং তাদের মানগুলির একটি অভিধান পেতে হবে? মনে হচ্ছে এটির জন্য প্রতিবিম্বটি ব্যবহার করা কার্যকর হবে না।

উদাহরণ:

dynamic s = new ExpandoObject();
s.Path = "/Home";
s.Name = "Home";

// How do I enumerate the Path and Name properties and get their values?
IDictionary<string, object> propertyValues = ???

উত্তর:


32

আইডিনামিকমেটাওজেক্টপ্রোভাইডার যদি গতিশীল সদস্যের নাম সরবরাহ করতে পারে তবে আপনি সেগুলি পেতে পারেন। দেখুন GetMemberNames Apache মধ্যে বাস্তবায়ন লাইসেন্সকৃত হছ্ছে পিসিএল গ্রন্থাগার Dynamitey (nuget খুঁজে পাওয়া যেতে পারে), এটা জন্য কাজ করে ExpandoObjects এবং DynamicObjectযে বাস্তবায়ন গুলি GetDynamicMemberNamesএবং অন্য কোন IDynamicMetaObjectProviderযারা একটি বাস্তবায়ন সঙ্গে একটি মেটা বস্তুর উপলব্ধ GetDynamicMemberNamesকাস্টম পরলোক পরীক্ষা ছাড়া is IDynamicMetaObjectProvider

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


17
কোডটি এই বিন্দুতে পৌঁছানোর জন্য ধন্যবাদ: var tTarget = IDynamicMetaObjectProvider হিসাবে লক্ষ্য; if (tTarget! = null) L tList.AddRange (tTarget.GetMetaObject (Expression.Constant (tTarget))। getDynamicMemberNames ()); }
ফ্ল্যাটলাইনার ডিওএ

আপনার দুর্দান্ত গ্রন্থাগার জন্য ধন্যবাদ। আমি বিষয় এই লাইব্রেরি একটি গতিশীল বস্তুর রাউন্ড-দ্রুতগামী চাপ ছিল dynamicjson.codeplex.com , এবং সক্ষম ছিল আপনার লাইব্রেরি সঙ্গে এটি সম্প্রসারিত করে।
জেজেএস

1
উদাহরণস্বরূপ
দেমডাভ

105

ExpandoObject এর ক্ষেত্রে, ExpandoObject বর্গটি আসলে IDictionary<string, object>তার বৈশিষ্ট্যগুলির জন্য প্রয়োগ করে, তাই সমাধানটি castালাইয়ের মতো তুচ্ছ ial

IDictionary<string, object> propertyValues = (IDictionary<string, object>)s;

নোট করুন যে এটি সাধারণ গতিশীল বস্তুর জন্য কাজ করবে না। এই ক্ষেত্রে আপনাকে আইডিনামিকমেটাওজেক্টপ্রোভিডার হয়ে ডিএলআর থেকে নামাতে হবে।


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

2
এটি কেবল এক্সপ্যান্ডোঅবজেক্ট শ্রেণীর অবজেক্টের জন্য কাজ করে, ডায়নামিকবজেক্ট ক্লাসটি আরেকটি এক্সটেনসিবল ক্লাস যা আইডোরিয়ালিটি প্রয়োগ করে না বরং আইডিনামিকমেটাওজেক্টপ্রোভাইডার প্রয়োগ করে।
শারিক আবদুল্লাহ

1
এটি যদিও ওপির প্রশ্নের উত্তর দেয় does
শারিক আবদুল্লাহ

58

বিবেচনা করার জন্য বেশ কয়েকটি পরিস্থিতি রয়েছে। প্রথমত, আপনাকে আপনার অবজেক্টের ধরণটি পরীক্ষা করতে হবে। আপনি কেবল এর জন্য getType () কল করতে পারেন। যদি টাইপটি IDynamicMetaObjectProvider বাস্তবায়ন না করে, তবে আপনি অন্য যে কোনও অবজেক্টের মতো প্রতিচ্ছবিটি ব্যবহার করতে পারেন। কিছুটা এইরকম:

var propertyInfo = test.GetType().GetProperties();

যাইহোক, IDynamicMetaObjectProvider বাস্তবায়নগুলির জন্য, সরল প্রতিবিম্ব কাজ করে না। মূলত, আপনাকে এই অবজেক্টটি সম্পর্কে আরও জানতে হবে। যদি এটি এক্সপেন্ডোঅবজেক্ট হয় (যা আইডিনামিকমেটাওজেক্টপ্রোভাডার বাস্তবায়নগুলির মধ্যে একটি), আপনি এটিউলসনের দেওয়া উত্তরটি ব্যবহার করতে পারেন। ExpandoObject এর অভিধানগুলিকে একটি অভিধানে সঞ্চয় করে এবং আপনি কেবল আপনার ডায়নামিক অবজেক্টটি কোনও অভিধানে কাস্ট করতে পারেন।

যদি এটি ডায়নামিকবজেক্ট (অন্য একটি আইডিনামিকমেটাওজেক্টপ্রোভাইডার বাস্তবায়ন) হয় তবে আপনার এই ডায়নামিকবজেক্টটি যে কোনও পদ্ধতি প্রকাশ করে তা আপনাকে ব্যবহার করতে হবে। ডায়নামিকবজেক্টকে এর সম্পত্তিগুলির তালিকা যে কোনও জায়গায় আসলে "স্টোর" করার দরকার নেই। উদাহরণস্বরূপ, এটি এর মতো কিছু করতে পারে (আমি আমার ব্লগ পোস্ট থেকে একটি উদাহরণ পুনরায় ব্যবহার করছি ):

public class SampleObject : DynamicObject
{
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = binder.Name;
        return true;
    }
}

এই ক্ষেত্রে, আপনি যখনই কোনও সম্পত্তি (কোনও প্রদত্ত নাম সহ) অ্যাক্সেস করার চেষ্টা করবেন তখন অবজেক্টটি কেবল স্ট্রিং হিসাবে সম্পত্তিটির নাম ফিরিয়ে দেয়।

dynamic obj = new SampleObject();
Console.WriteLine(obj.SampleProperty);
//Prints "SampleProperty".

সুতরাং, আপনার প্রতিফলিত করার মতো কিছু নেই - এই সামগ্রীর কোনও বৈশিষ্ট্য নেই এবং একই সাথে সমস্ত বৈধ সম্পত্তি নাম কাজ করবে work

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


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

2
গতিশীল সদস্যদের তালিকার নামগুলি ফেরত দেওয়ার জন্য আপনি গতিশীল বস্তুর জন্য getDynamicMemberNames () পদ্ধতিটি ওভাররাইড করতে পারেন। সমস্যাটি হ'ল এটি নিশ্চিত হয় না যে প্রতিটি গতিশীল অবজেক্টের এই পদ্ধতি রয়েছে (ExpandoObject না)। এটি আশ্চর্যজনক নয় যে স্ট্যাটিক ধরণের জন্য প্রতিবিম্ব আরও ভাল কাজ করে। এটি তাদের জন্য প্রথম স্থানে তৈরি করা হয়েছিল। গতিশীলতার সাথে আপনাকে ইউনিট-টেস্টিং এবং টিডিডির উপর বেশি নির্ভর করতে হবে।
আলেকজান্দ্রা রুসিনা

1
গেটডিনমিক মেম্বারনামসের জন্য এমএসডিএন ডকুমেন্টেশন () উল্লেখ করেছে: "এই পদ্ধতিটি কেবলমাত্র ডিবাগিংয়ের উদ্দেশ্যেই বিদ্যমান" ", সত্যিই সান্ত্বনা দেয় না :(
নিকো জুইসিশ

19

নিউটনসফট জসন. নেট প্রয়োজন

একটু দেরি হলেও এ নিয়ে এসেছি। এটি আপনাকে কেবল কীগুলি দেয় এবং তারপরে আপনি গতিশীলরা সেগুলি ব্যবহার করতে পারেন:

public List<string> GetPropertyKeysForDynamic(dynamic dynamicToGetPropertiesFor)
{
    JObject attributesAsJObject = dynamicToGetPropertiesFor;
    Dictionary<string, object> values = attributesAsJObject.ToObject<Dictionary<string, object>>();
    List<string> toReturn = new List<string>();
    foreach (string key in values.Keys)
    {
        toReturn.Add(key);                
    }
    return toReturn;
}

তারপরে আপনি কেবল এইভাবে ভবিষ্যদ্বাণী করুন:

foreach(string propertyName in GetPropertyKeysForDynamic(dynamicToGetPropertiesFor))
{
    dynamic/object/string propertyValue = dynamicToGetPropertiesFor[propertyName];
    // And
    dynamicToGetPropertiesFor[propertyName] = "Your Value"; // Or an object value
}

স্ট্রিং বা অন্য কোনও অবজেক্ট হিসাবে মান পাওয়ার জন্য বা অন্য গতিশীল করার জন্য এবং আবার অনুসন্ধানটি ব্যবহার করতে বেছে নেওয়া হচ্ছে।


রিটার্নে আপনার তালিকার দরকার নেই।
এলোআইএসডিজি

4
পারফেক্ট! আমাকে জবজেক্ট বৈশিষ্ট্যগুলি এজেজেবজেক্ট = ডায়নামিকটোগেটপ্রোটের জন্য পরিবর্তন করতে হয়েছিল; টু অবজেক্ট অ্যাট্রিবিউটস এজেজেবজেক্ট = (জবজেক্ট) জটোকেন.ফ্রমঅবজেক্ট (অবজেক্ট); যদিও !!
k25

@ কে 25 যা বলেছিল তা কেবল পুনরাবৃত্তি করার জন্য। আপনি প্রতিস্থাপন করা প্রয়োজন JObject attributesAsJObject = dynamicToGetPropertiesFor;ভালো কিছু সঙ্গে var jObject = (JObject) JToken.FromObject(dynamicToGetPropertiesFor);। এই মুহুর্তে, আপনি এমন কিছু করে সম্পত্তির নাম এবং মানগুলির একটি অভিধান পেতে পারেন var objProperties = jObject.ToObject<Dictionary<string, object>>();। হাতে যে, আপনি দৌড় বন্ধ। এর জন্য ডায়নামিকের দরকার নেই। এটা তোলে কিছু যে একটি এর উপশ্রেণী সঙ্গে কাজ করে জরিমানাDynamicObject
Flydog57
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.