यहाँ एक System.Type
गतिशील रूप से ऑब्जेक्ट को कास्ट करने का मेरा तरीका है, लेकिन जेनेरिक टाइप वेरिएबल के लिए नहीं, बल्कि :
मैं रन-टाइम का उपयोग करते हुए एक लैंबडा एक्सप्रेशन बनाता हूं, System.Linq.Expressions
प्रकार का Func<object, object>
, जो इसके इनपुट को अनबॉक्स करता है, वांछित प्रकार का रूपांतरण करता है और फिर परिणाम को बॉक्सिंग देता है। एक नए को न केवल उन सभी प्रकारों की आवश्यकता होती है, जो उन्हें डाले जाते हैं, बल्कि उन प्रकारों के लिए भी होते हैं जो ढल जाते हैं (अनबॉक्सिंग स्टेप के कारण)। इन अभिव्यक्तियों को बनाने में अत्यधिक समय लगता है, क्योंकि प्रतिबिंब के कारण, संकलन और गतिशील विधि निर्माण जो हुड के तहत किया जाता है। सौभाग्य से एक बार निर्मित होने पर, अभिव्यक्तियों को बार-बार और उच्च ओवरहेड के बिना लागू किया जा सकता है, इसलिए मैं प्रत्येक को कैश करता हूं।
private static Func<object, object> MakeCastDelegate(Type from, Type to)
{
var p = Expression.Parameter(typeof(object)); //do not inline
return Expression.Lambda<Func<object, object>>(
Expression.Convert(Expression.ConvertChecked(Expression.Convert(p, from), to), typeof(object)),
p).Compile();
}
private static readonly Dictionary<Tuple<Type, Type>, Func<object, object>> CastCache
= new Dictionary<Tuple<Type, Type>, Func<object, object>>();
public static Func<object, object> GetCastDelegate(Type from, Type to)
{
lock (CastCache)
{
var key = new Tuple<Type, Type>(from, to);
Func<object, object> cast_delegate;
if (!CastCache.TryGetValue(key, out cast_delegate))
{
cast_delegate = MakeCastDelegate(from, to);
CastCache.Add(key, cast_delegate);
}
return cast_delegate;
}
}
public static object Cast(Type t, object o)
{
return GetCastDelegate(o.GetType(), t).Invoke(o);
}
ध्यान दें कि यह जादू नहीं है। कास्टिंग कोड में नहीं होती है, जैसा कि यह dynamic
कीवर्ड के साथ करता है , केवल ऑब्जेक्ट का अंतर्निहित डेटा परिवर्तित हो जाता है। संकलन-समय पर हम अभी भी श्रमसाध्य रूप से यह जानने के लिए शेष हैं कि हमारी वस्तु किस प्रकार की हो सकती है, जिससे यह समाधान अव्यावहारिक हो जाता है। मैंने इसे मनमाने प्रकारों द्वारा परिभाषित रूपांतरण ऑपरेटरों को आह्वान करने के लिए एक हैक के रूप में लिखा था, लेकिन शायद कोई व्यक्ति बेहतर उपयोग के मामले को खोज सकता है।