Определите, представляют ли два экземпляра MethodInfo один и тот же (не виртуальный) метод посредством наследования
Сначала я приведу простой пример, где я знаю ответ. Рассматривать:
class Animal
{
public virtual void M() { Console.WriteLine("a"); }
}
class Giraffe : Animal
{
public override void M() { Console.WriteLine("g"); }
}
а потом где-то код:
var am = typeof(Animal).GetMethod("M");
var gm = typeof(Giraffe).GetMethod("M");
Console.WriteLine(am == gm); // False
Console.WriteLine(am == gm.GetBaseDefinition()); // True
Мы видим, что am
а также gm
не считаются равными, что вполне справедливо (последнее является переопределением первого). Однако с последней строкой мы можем определить, что эти два метода связаны; один является "базовым методом" другого.
(Вы даже можете проверить равенство ссылок, (object)am == (object)gm.GetBaseDefinition()
, и вы все еще получаете True.)
И теперь для ситуации у меня есть вопрос. Рассмотрим вместо этого:
class Plant
{
public void N() /* non-virtual */ { }
}
class Tree : Plant
{
}
с:
var pn = typeof(Plant).GetMethod("N");
var tn = typeof(Tree).GetMethod("N");
Console.WriteLine(pn == tn); // False
// How can I determine that 'pn' and 'tn' are in a sense the same method?
В этом случае pn
а также tn
все еще считаются разными (и их ReflectedType
отличается).
Как я могу проверить, действительно ли они (через наследование) один и тот же метод?
Есть ли встроенный метод в рамках? Если мне придется решить это вручную, какова стратегия? Должен ли я проверить, что оба имеют одинаковые DeclaringType
, имеют одинаковые списки (типов) параметров и имеют одинаковое количество параметров типа?
1 ответ
Вы можете использовать DeclaringType
имущество:
am.DeclaringType.Dump(); // Animal
gm.DeclaringType.Dump(); // Giraffe
pn.DeclaringType.Dump(); // Plant
tn.DeclaringType.Dump(); // Plant
Или вы можете использовать MethodHandle
:
(am.MethodHandle == gm.MethodHandle).Dump(); // False
(pn.MethodHandle == tn.MethodHandle).Dump(); // True
Хотя я не уверен, что это полностью надежно.
Если вас интересует только переопределение метода в данном типе, вы также можете использовать BindingFlags
:
var flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
typeof(Plant).GetMethod("N", flags).Dump(); // N
typeof(Tree).GetMethod("N", flags).Dump(); // null