كيفية الوصول إلى الخصائص ديناميكية / متأخرة؟
-
01-10-2019 - |
سؤال
أرغب في تنفيذ طريقة تسمح لي بالوصول إلى خاصية لكائن غير معروف / مجهول (-Graph) بطريقة متأخرة / ديناميكية (لا أعرف حتى كيفية تسميتها بشكل صحيح).
إليك مثال على ما أود تحقيقه:
// setup an anonymous object
var a = new { B = new { C = new { I = 33 } } };
// now get the value of a.B.C.I in a late-bound way
var i = Get(a, "B.C.I");
وإليك تطبيق بسيط باستخدام الانعكاس "الكلاسيكي":
public static object Get(object obj, string expression)
{
foreach (var name in expression.Split('.'))
{
var property = obj.GetType().GetProperty(name);
obj = property.GetValue(obj, null);
}
return obj;
}
ما هي الخيارات الأخرى التي لدي مع C# / .NET 4 لتنفيذ شيء مماثل كما هو موضح أعلاه ، ولكن ربما يكون أبسط وأكثر أداءً ، وما إلى ذلك؟
ربما هناك طرق لتحقيق نفس الشيء ، مما يسمح لي بتحديد expression
باستخدام تعبير lambda بدلا من سلسلة؟ هل ستكون أشجار التعبير مفيدة بأي شكل من الأشكال (على سبيل المثال كما هو موضح في هذا السؤال)?
تحديث: يتم تمرير الكائن والتعبير إلى الكود الخاص بي عبر مكالمة خدمة الويب. لهذا السبب استخدمت object
و string
في Get()
طريقة.
المحلول
هل أنت في الحقيقة فقط التعبير كسلسلة؟ هل من المعروف في وقت الترجمة ، فقط أن الأنواع نفسها ليست معروفة (أو يصعب التعبير عنها)؟ لو ذلك:
dynamic d = a;
int i = d.B.C.I;
اذا أنت حقًا فقط لديك كسلسلة (على سبيل المثال كبيانات ذات إدخال مستخدم) تجعل الحياة أكثر صعوبة ، ولا تساعدك أي من ميزات C# 4 حقًا. من المحتمل أن تقوم بتقييمه كنص محدد Ironpython أو شيء من هذا القبيل ...
تحرير: حسنًا ، بعد التحديث ، يبدو أنك في الموقف الأخير - وفي هذه الحالة ، لا أعرف طريقة أجمل من استخدام التفكير. قد تساعد بعض ملزمة الممتلكات المدمجة المصنفة لواجهة المستخدم ، لكنني لا أعرف طريقة نظيفة للوصول إليها.
نصائح أخرى
إذا كنت ترغب في استخدام نمط C# ، فيمكنك استخدام برنامج التحويل البرمجي Mono كخدمة من التطبيق الخاص بك. أصف كيفية القيام بذلك هنا:برنامج التحويل البرمجي أحادي كخدمة (MCS)
كنهج بديل ، يمكنك استخدام الانعكاس لوضع جميع خصائص كائنك في توسيع نطاق ، ثم استخدامه مثل القاموس (لأن expressoObject ينفذ المعرف). بدلاً من ذلك ، يمكنك استخدام json.net و call JObject.FromObject
, ، والذي سيحول كائنًا منتظمًا إلى وظيفة يمكن الوصول إليها بأسلوب يشبه القاموس (وكفائدة إضافية لها دعم الرسم البياني المتكرر). أخيرًا ، يمكنك استخدام نفس النهج لتفريغ كائنك في قاموس القواميس.