Detect If a Method Was Overridden Using Reflection (C#)

Detect if a method was overridden using Reflection (C#)

Given the type Test1, you can determine whether it has its own implementation declaration of TestMe:

typeof(Test1).GetMethod("TestMe").DeclaringType == typeof(Test1)

If the declaration came from a base type, this will evaluate false.

Note that since this is testing declaration, not true implementation, this will return true if Test1 is also abstract and TestMe is abstract, since Test1 would have its own declaration. If you want to exclude that case, add && !GetMethod("TestMe").IsAbstract

Test if a method is an override?

You can use MethodInfo.DeclaringType to determine if the method is an override (assuming that it's also IsVirtual = true).

From the documentation:

...note that when B overrides virtual
method M from A, it essentially
redefines (or redeclares) this method.
Therefore, B.M's MethodInfo reports
the declaring type as B rather than A,
even though A is where this method was
originally declared...

Here's an example:

var someType = typeof(BabyFoo);
var mi = someType.GetMethod("GimmeIntPleez");
// assuming we know GimmeIntPleez is in a base class, it must be overriden
if( mi.IsVirtual && mi.DeclaringType == typeof(BabyFoo) )
{ ... }

How to detect if virtual method is overridden in c#

Check this out: Detect if a method was overridden using Reflection (C#)

Reflection would be the only way to do this at runtime. This should come with a health warning however, it should be considered a Very Bad Idea™ from an OOP perspective. A base class should not generally know or care how a derived class is implemented.

How to check if method is overridden inside a type ? Reflection C#

You can use the binding flags to your advantage:

var t = typeof(mytype).GetMethod(
"Equals",
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly
);

Then t is not null if and only if mytype overrides Equals.

Test whether virtual method has been overridden


public class BaseClass
{
public bool SupportsA
{
get { return (this.GetType().GetMethod("A").DeclaringType == typeof(BaseClass)); }
}
public virtual void A()
{
// Null default implementation.
}
}

Determine whether a C# method has keyword 'override' using Reflection

Well, I don't see how that would come into play either. Your code there does indeed determine whether a method is defined or overriden.

In the case of hiding, the declaring type is the one that hides the method via new.
In the case of generics, all methods are defined by the template class.

How to determine if the MethodInfo is an override of the base method

Check its DeclaringType property.

if (methodInfo.DeclaringType == typeof(Foo)) {
// ...
}

Is there a way to override a method with reflection?

The first part of this answer is wrong, I'm only leaving it so that the evolution in the comments makes sense. Please see the EDIT(s).

You're not looking for reflection, but emission (which is the other way around).

In particular, there's a method that does just what you want, lucky you!

See TypeBuilder.DefineMethodOverride

EDIT:
Writing this answer, I just remembered that re-mix allows you to do this too. It's way harder though.

Re-mix is a framework that "simulates" mixins in C#. In its basic aspect, you can think of it as interfaces with default implementations. If you go further, it becomes much more than that.

EDIT 2: Here is an example of use for re-mix (implementing INotifyPropertyChanged on a class that doesn't support it, and has no idea of mixins).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Remotion.Mixins;
using System.ComponentModel;
using MixinTest;

[assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))]

namespace MixinTest
{
//[Remotion.Mixins.CompleteInterface(typeof(INPCTester))]
public interface ICustomINPC : INotifyPropertyChanged
{
void RaisePropertyChanged(string prop);
}

//[Extends(typeof(INPCTester))]
public class INotifyPropertyChangedMixin : Mixin<object>, ICustomINPC
{
public event PropertyChangedEventHandler PropertyChanged;

public void RaisePropertyChanged(string prop)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(prop));
}
}
}

public class ImplementsINPCAttribute : UsesAttribute
{
public ImplementsINPCAttribute()
: base(typeof(INotifyPropertyChangedMixin))
{

}
}

//[ImplementsINPC]
public class INPCTester
{
private string m_Name;
public string Name
{
get { return m_Name; }
set
{
if (m_Name != value)
{
m_Name = value;
((ICustomINPC)this).RaisePropertyChanged("Name");
}
}
}
}

public class INPCTestWithoutMixin : ICustomINPC
{
private string m_Name;
public string Name
{
get { return m_Name; }
set
{
if (m_Name != value)
{
m_Name = value;
this.RaisePropertyChanged("Name");
}
}
}

public void RaisePropertyChanged(string prop)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(prop));
}
}

public event PropertyChangedEventHandler PropertyChanged;
}
}

And the test:

static void INPCImplementation()
{
Console.WriteLine("INPC implementation and usage");

var inpc = ObjectFactory.Create<INPCTester>(ParamList.Empty);

Console.WriteLine("The resulting object is castable as INPC: " + (inpc is INotifyPropertyChanged));

((INotifyPropertyChanged)inpc).PropertyChanged += inpc_PropertyChanged;

inpc.Name = "New name!";
((INotifyPropertyChanged)inpc).PropertyChanged -= inpc_PropertyChanged;
Console.WriteLine();
}

static void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("Hello, world! Property's name: " + e.PropertyName);
}
//OUTPUT:
//INPC implementation and usage
//The resulting object is castable as INPC: True
//Hello, world! Property's name: Name

Please note that:

[assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))]

and

[Extends(typeof(INPCTester))] //commented out in my example

and

[ImplementsINPC] //commented out in my example

Have the exact same effect. It is a matter of where you wish to define that a particular mixin is applied to a particular class.

Example 2: overriding Equals and GetHashCode

public class EquatableByValuesMixin<[BindToTargetType]T> : Mixin<T>, IEquatable<T> where T : class
{
private static readonly FieldInfo[] m_TargetFields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

bool IEquatable<T>.Equals(T other)
{
if (other == null)
return false;
if (Target.GetType() != other.GetType())
return false;
for (int i = 0; i < m_TargetFields.Length; i++)
{
object thisFieldValue = m_TargetFields[i].GetValue(Target);
object otherFieldValue = m_TargetFields[i].GetValue(other);

if (!Equals(thisFieldValue, otherFieldValue))
return false;
}
return true;
}

[OverrideTarget]
public new bool Equals(object other)
{
return ((IEquatable<T>)this).Equals(other as T);
}

[OverrideTarget]
public new int GetHashCode()
{
int i = 0;
foreach (FieldInfo f in m_TargetFields)
i ^= f.GetValue(Target).GetHashCode();
return i;
}
}

public class EquatableByValuesAttribute : UsesAttribute
{
public EquatableByValuesAttribute()
: base(typeof(EquatableByValuesMixin<>))
{

}
}

That example is my implementation of the hands-on lab given with re-mix. You can find more information there.



Related Topics



Leave a reply



Submit