استرجاع اسم الأسلوب الذي تم استدعاؤه تنفيذها في وظائفها
-
22-07-2019 - |
سؤال
وأود أن الحصول على اسم الأسلوب الذي يتم تفويض باعتباره وظائفها.
Func<MyObject, object> func = x => x.DoSomeMethod();
string name = ExtractMethodName(func); // should equal "DoSomeMethod"
وكيف يمكنني تحقيق ذلك؟
و- للحقوق المفاخرة -
تأكد ExtractMethodName
يعمل أيضا مع الاحتجاج الملكية، وبعد ذلك يعود اسم الخاصية في هذا المثال.
وعلى سبيل المثال.
Func<MyObject, object> func = x => x.Property;
string name = ExtractMethodName(func); // should equal "Property"
المحلول
وانظروا ما! لا أشجار التعبير!
وهنا، نسخة سريعة القذرة وتنفيذ محددة أن الاستيلاء على رمز التعريف من تيار IL لامدا الكامنة ويحل عليه.
private static string ExtractMethodName(Func<MyObject, object> func)
{
var il = func.Method.GetMethodBody().GetILAsByteArray();
// first byte is ldarg.0
// second byte is callvirt
// next four bytes are the MethodDef token
var mdToken = (il[5] << 24) | (il[4] << 16) | (il[3] << 8) | il[2];
var innerMethod = func.Method.Module.ResolveMethod(mdToken);
// Check to see if this is a property getter and grab property if it is...
if (innerMethod.IsSpecialName && innerMethod.Name.StartsWith("get_"))
{
var prop = (from p in innerMethod.DeclaringType.GetProperties()
where p.GetGetMethod() == innerMethod
select p).FirstOrDefault();
if (prop != null)
return prop.Name;
}
return innerMethod.Name;
}
نصائح أخرى
وأنا لا أعتقد أن هذا ممكن في الحالة العامة. ماذا لو كان لديك:
Func<MyObject, object> func = x => x.DoSomeMethod(x.DoSomeOtherMethod());
وماذا تتوقع؟
وأن يقال، هل يمكن استخدام انعكاس لفتح الكائن وظائفها ونرى ما تقوم به في الداخل، ولكن عليك أن تكون قادرا على حلها لبعض الحالات فقط.
وراجع جوابي الإختراق هنا:
لماذا ليست هناك `fieldof `` أو مشغل methodof` في C #؟
في الماضي كنت فعلت ذلك بطريقة أخرى أن تستخدم Func
بدلا من Expression<Func<...>>
، لكنني كنت أقل يسر كثيرا بالنتيجة. وMemberExpression
تستخدم لكشف الميدان في بلدي طريقة fieldof
سيعود PropertyInfo
عند استخدام خاصية.
وتحرير # 1: هذا يعمل لمجموعة فرعية من هذه المشكلة:
Func<object> func = x.DoSomething;
string name = func.Method.Name;
وتحرير # 2: من شهد لي أسفل يجب أن تأخذ ثانية لتحقيق ما يحدث هنا. أشجار التعبير يمكن استخدام ضمنا مع تعبيرات لامدا وأسرع وأنجع وسيلة للحصول على المعلومات المحددة المطلوبة هنا.