উত্তর:
এমএসডিএন অনুসারে ঘোষণাপত্রটি দেখায় যে এটি আইডি অভিধান প্রয়োগ করছে:
public sealed class ExpandoObject : IDynamicMetaObjectProvider,
IDictionary<string, Object>, ICollection<KeyValuePair<string, Object>>,
IEnumerable<KeyValuePair<string, Object>>, IEnumerable, INotifyPropertyChanged
কোনও সদস্য সংজ্ঞায়িত হয়েছে কিনা তা দেখতে আপনি এটি ব্যবহার করতে পারেন:
var expandoObject = ...;
if(((IDictionary<String, object>)expandoObject).ContainsKey("SomeMember")) {
// expandoObject.SomeMember exists.
}
একটি গুরুত্বপূর্ণ পার্থক্য এখানে করা প্রয়োজন।
এখানে বেশিরভাগ উত্তরই ExpandoObject এর সাথে সুনির্দিষ্ট যা প্রশ্নে উল্লেখ করা হয়েছে। তবে একটি সাধারণ ব্যবহার (এবং অনুসন্ধানের সময় এই প্রশ্নে অবতরণের কারণ) হ'ল এএসপি.নেট এমভিসি ভিউব্যাগটি ব্যবহার করার সময়। এটি ডাইনামিকবজেক্টের একটি কাস্টম বাস্তবায়ন / সাবক্লাস, যা আপনি কোনও নালীর জন্য যেকোন স্বেচ্ছাসেবী সম্পত্তির নাম চেক করলে কোনও ব্যতিক্রম ছুঁড়ে না ফেলে। মনে করুন আপনি কোনও সম্পত্তি যেমন ঘোষণা করতে পারেন:
@{
ViewBag.EnableThinger = true;
}
তাহলে ধরুন আপনি এর মানটি পরীক্ষা করতে চেয়েছিলেন এবং এটি এমনকি সেট করা আছে কিনা - এটি বিদ্যমান কিনা। নিম্নলিখিতটি বৈধ, সংকলন করবে, কোনও ব্যতিক্রম ছোঁড়াবে না এবং আপনাকে সঠিক উত্তর দেয়:
if (ViewBag.EnableThinger != null && ViewBag.EnableThinger)
{
// Do some stuff when EnableThinger is true
}
এখনই সক্ষমকরণ-টিজার ঘোষণা থেকে মুক্তি পান। একই কোড সংকলন করে সঠিকভাবে চলে। প্রতিবিম্বের দরকার নেই।
ভিউব্যাগ থেকে ভিন্ন, ExpandoObject নিক্ষেপ করবে যদি আপনি এমন কোনও সম্পত্তি নেই যা অস্তিত্বহীন রয়েছে on আপনার নিজের থেকে এমভিসি ভিউব্যাগের মৃদু কার্যকারিতাটি পেতেdynamic
অবজেক্টগুলির , আপনাকে গতিশীল করার একটি প্রয়োগ ব্যবহার করতে হবে যা ছুঁড়ে না।
আপনি কেবল এমভিসি ভিউব্যাগে সঠিক প্রয়োগটি ব্যবহার করতে পারেন:
. . .
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = ViewData[binder.Name];
// since ViewDataDictionary always returns a result even if the key does not exist, always return true
return true;
}
. . .
আপনি এটি এখানে এমভিসি ভিউতে এমভিসি ভিউপেজে বাঁধা দেখতে পাচ্ছেন:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
ডায়নামিকভিউডাটা ডেটাডিয়েশনারের কৌতূহলপূর্ণ আচরণের মূল চাবিকাঠি এখানে ভিউডাটাডিয়েশনারি অভিধান অভিধান প্রয়োগ করা হয়:
public object this[string key]
{
get
{
object value;
_innerDictionary.TryGetValue(key, out value);
return value;
}
set { _innerDictionary[key] = value; }
}
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ViewDataDictionary.cs
অন্য কথায়, এটি সর্বদা কীগুলির মধ্যে মূল্য নির্বিশেষে সমস্ত কীগুলির জন্য একটি মান প্রদান করে - কিছুই না থাকায় এটি কেবল শূন্য হয়ে যায়। তবে, ভিভিডাটাডেটরিয়ায় এমভিসির মডেলটির সাথে আবদ্ধ হওয়ার বোঝা রয়েছে, সুতরাং এমভিসি ভিউগুলির বাইরে ব্যবহারের জন্য কেবল দৃষ্টিনন্দন অভিধানের অংশগুলি ছাঁটাই করা ভাল।
এখানে সমস্ত সাহস পোস্ট করার জন্য এটি বেশ দীর্ঘ - এর বেশিরভাগই কেবল আইডোরিয়াস বাস্তবায়ন করে - তবে এখানে একটি গতিশীল অবজেক্ট (শ্রেণি DDict
) রয়েছে যা তে ঘোষিত হয়নি এমন সম্পত্তিগুলির নাল চেকের জন্য নিক্ষেপ করে না:
https://github.com/b9chris/GracefulDynamicDictionary
আপনি শুধু NuGet এর মাধ্যমে আপনার প্রকল্প এটি যোগ করতে চান, তাহলে এটির নাম GracefulDynamicDictionary ।
আমি সম্প্রতি একটি খুব অনুরূপ প্রশ্নের উত্তর দিয়েছি: আমি কীভাবে গতিশীল অবজেক্টের সদস্যদের প্রতিফলিত করব?
সংক্ষেপে, ExpandoObject আপনি পেতে পারেন কেবল গতিশীল অবজেক্ট নয়। প্রতিবিম্ব স্ট্যাটিক প্রকারের জন্য (আইডিনামিকমেটাওজেক্টপ্রোভাইডার প্রয়োগ না করে এমন প্রকারের) জন্য কাজ করবে। এই ইন্টারফেসটি প্রয়োগ করে এমন ধরণের ক্ষেত্রে, প্রতিফলনটি মূলত অকেজো। ExpandoObject এর জন্য, আপনি কেবল অন্তর্নিহিত অভিধানে সম্পত্তিটি কী হিসাবে সংজ্ঞায়িত হয়েছে কিনা তা খতিয়ে দেখতে পারেন। অন্যান্য বাস্তবায়নের জন্য, এটি চ্যালেঞ্জ হতে পারে এবং কখনও কখনও ব্যতিক্রম ছাড়া কাজ করার একমাত্র উপায়। বিস্তারিত জানার জন্য উপরের লিঙ্কটি অনুসরণ করুন।
আপডেট করা: আপনি প্রতিনিধিদের ব্যবহার করতে পারেন এবং যদি এটি বিদ্যমান থাকে তবে গতিশীল অবজেক্টের সম্পত্তি থেকে একটি মান পাওয়ার চেষ্টা করতে পারেন। কোনও সম্পত্তি না থাকলে কেবল ব্যতিক্রমটি ধরুন এবং মিথ্যা প্রত্যাবর্তন করুন।
একবার দেখুন, এটি আমার পক্ষে ভাল কাজ করে:
class Program
{
static void Main(string[] args)
{
dynamic userDynamic = new JsonUser();
Console.WriteLine(IsPropertyExist(() => userDynamic.first_name));
Console.WriteLine(IsPropertyExist(() => userDynamic.address));
Console.WriteLine(IsPropertyExist(() => userDynamic.last_name));
}
class JsonUser
{
public string first_name { get; set; }
public string address
{
get
{
throw new InvalidOperationException("Cannot read property value");
}
}
}
static bool IsPropertyExist(GetValueDelegate getValueMethod)
{
try
{
//we're not interesting in the return value. What we need to know is whether an exception occurred or not
getValueMethod();
return true;
}
catch (RuntimeBinderException)
{
// RuntimeBinderException occurred during accessing the property
// and it means there is no such property
return false;
}
catch
{
//property exists, but an exception occurred during getting of a value
return true;
}
}
delegate string GetValueDelegate();
}
কোডের আউটপুট নিম্নলিখিত:
True
True
False
IsPropertyExist
। এই উদাহরণে, আপনি জানেন যে কেউ একটি নিক্ষেপ করতে পারে InvalidOperationException
। অনুশীলনে, কোন ব্যতিক্রম নিক্ষেপ করা হতে পারে তা আপনার কোনও ধারণা নেই। কার্গো ধর্মের প্রতিবাদের জন্য +1
আমি একটি এক্সটেনশন পদ্ধতি তৈরি করতে চেয়েছিলাম যাতে আমি এর মতো কিছু করতে পারি:
dynamic myDynamicObject;
myDynamicObject.propertyName = "value";
if (myDynamicObject.HasProperty("propertyName"))
{
//...
}
... তবে আপনি ExpandoObject
সি # 5 ডকুমেন্টেশন অনুসারে এক্সটেনশন তৈরি করতে পারবেন না ( এখানে আরও তথ্য )।
সুতরাং আমি একটি ক্লাস সহায়ক তৈরি করে শেষ করেছি:
public static class ExpandoObjectHelper
{
public static bool HasProperty(ExpandoObject obj, string propertyName)
{
return ((IDictionary<String, object>)obj).ContainsKey(propertyName);
}
}
এটি ব্যবহার করতে:
// If the 'MyProperty' property exists...
if (ExpandoObjectHelper.HasProperty(obj, "MyProperty"))
{
...
}
আপনি টাইপ যথাযথ সেটগুলি পেতে প্রতিবিম্বটি কেন ব্যবহার করতে চান না? এটার মত
dynamic v = new Foo();
Type t = v.GetType();
System.Reflection.PropertyInfo[] pInfo = t.GetProperties();
if (Array.Find<System.Reflection.PropertyInfo>(pInfo, p => { return p.Name == "PropName"; }). GetValue(v, null) != null))
{
//PropName initialized
}
এই এক্সটেনশন পদ্ধতিটি কোনও সংস্থার অস্তিত্বের জন্য পরীক্ষা করে এবং তারপরে মান বা নাল ফেরায়। এটি যদি আপনার অ্যাপ্লিকেশনগুলি অপ্রয়োজনীয় ব্যতিক্রম ছুঁড়ে না দিতে চায় তবে এটি কার্যকর হয়, কমপক্ষে যা আপনি সহায়তা করতে পারেন।
public static object Value(this ExpandoObject expando, string name)
{
var expandoDic = (IDictionary<string, object>)expando;
return expandoDic.ContainsKey(name) ? expandoDic[name] : null;
}
যদি এটির মতো ব্যবহার করা যায়:
// lookup is type 'ExpandoObject'
object value = lookup.Value("MyProperty");
অথবা যদি আপনার স্থানীয় ভেরিয়েবলটি 'ডায়নামিক' হয় তবে আপনাকে প্রথমে এটি ExpandoObject এ কাস্ট করতে হবে।
// lookup is type 'dynamic'
object value = ((ExpandoObject)lookup).Value("PropertyBeingTested");
আপনার ব্যবহারের ক্ষেত্রে, যদি শূন্যটিকে অপরিজ্ঞাত হিসাবে একই হিসাবে বিবেচনা করা যায় তবে আপনি আপনার ExpandoObjectটিকে ডায়নামিকজেসনঅজেক্টে রূপান্তর করতে পারেন।
dynamic x = new System.Web.Helpers.DynamicJsonObject(new ExpandoObject());
x.a = 1;
x.b = 2.50;
Console.WriteLine("a is " + (x.a ?? "undefined"));
Console.WriteLine("b is " + (x.b ?? "undefined"));
Console.WriteLine("c is " + (x.c ?? "undefined"));
আউটপুট:
a is 1
b is 2.5
c is undefined
(authorDynamic as ExpandoObject).Any(pair => pair.Key == "YourProp");
আরে ছেলেরা প্রত্যেকটির প্রতিচ্ছবি ব্যবহার করা বন্ধ করে দেয় যার জন্য প্রচুর সিপিইউ চক্র ব্যয় হয়।
সমাধান এখানে:
public class DynamicDictionary : DynamicObject
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
public int Count
{
get
{
return dictionary.Count;
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
string name = binder.Name;
if (!dictionary.TryGetValue(binder.Name, out result))
result = "undefined";
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
}
আর একবার চেষ্টা কর
public bool PropertyExist(object obj, string propertyName)
{
return obj.GetType().GetProperty(propertyName) != null;
}
dynamic
বস্তুর সাথে কাজ করে না (সর্বদা ফিরে আসে null
)।
data.myProperty
; এটি কিtypeof data.myProperty
ফিরে আসে তা পরীক্ষা করে । এটি সঠিক যেdata.myProperty
বিদ্যমান থাকতে পারে এবং সেট করা যেতে পারেundefined
, তবে সেই ক্ষেত্রে,typeof
ব্যতীত অন্য কিছু ফিরে আসবে"undefined"
। সুতরাং এই কোড কাজ করে।