c# How to detect if a particular method has overloaded versions? - c#

I just need to know if there's a smart way to detect if a particular Type method has overloads or not.
At the moment I'm iterating through methods and searching for DeclaringType+Name ambiguity...but I think it's a bit lame :)

The overload is what happens when you have two methods with the same name but different signatures.
So if we can the method is override by check method name whether more than one.
I would create an extension method IsOverloads to make it.
use the IsOverloads method need to provide at least two parameter
the class Type.
check method name
Using reflection to gets method information from the class, then check the method name greater than one means the method is overload.
public static class Ext {
public static bool IsOverloads(this Type type,string methodName)
{
return IsOverloads(type, methodName, BindingFlags.Public | BindingFlags.Instance);
}
public static bool IsOverloads(this Type type,
string methodName,
BindingFlags flags)
{
var info = type.GetMethods(flags);
return info.Where(o1 => o1.Name == methodName).Count() > 1;
}
}
Here is a simple
public class Program
{
public void Test() { }
public void Test(int a) { }
public void TestNo(int a) { }
public static void Main()
{
Console.WriteLine(typeof(Program).IsOverloads("Test")); //True
Console.WriteLine(typeof(Program).IsOverloads("TestNo")); //false
}
}
c# online

Related

Invoke expects an argument

public static void WaitUntilElementVisible(Action<string> preAction = null)
{
preAction?.Invoke();
}
static void Main(string[] args)
{
WaitUntilElementVisible((str) => PanelHandler("in"));
}
public static void PanelHandler(string className)
{
// do something
}
I want to execute PanelHandler("in") if its not null inside the WaitUntilElementVisible() method. However the Invoke() expects a string. But the strange thing is that I'm already giving it a string when I do WaitUntilElementVisible(() => PanelHandler("in")); how can I make Invoke use the string which I pass via lambda?
I want to call WaitUntilElementVisible() in such a way that WaitUntilElementVisible() will invoke PanelHandler with "in".
Your WaitUntilElementVisible is using an Action<string> delegate which is simply a reference to a method that expects a string argument but it does not know anything about the concrete method you want to call, in your example, the reference being used is the anonymous method you create with your lambda expression (str) =>, then, that method calls your actual method but you have already passed the reference of the original method!
If you convert the anonymous method to a regular one it is easier to understand what is happening:
static void Main(string[] args)
{
WaitUntilElementVisible(MyActionMethod);
}
public static void WaitUntilElementVisible(Action<string> preAction = null)
{
preAction?.Invoke();
}
public static void MyActionMethod(string str)
{
PanelHandler("in");
}
public static void PanelHandler(string className)
{
Console.WriteLine(className);
}
As you can see the reference you are passing is to MyActionMethod and not to PanelHandler and the str parameter is not used at all.
So you need to add a string argument to your method to pass the value and then you have the reference to the method and the value you need to pass:
static void Main(string[] args)
{
WaitUntilElementVisible(PanelHandler, "in");
}
public static void WaitUntilElementVisible(Action<string> preAction = null, string value = null)
{
preAction?.Invoke(value);
}
public static void PanelHandler(string className)
{
Console.WriteLine(className);
}
Or you can remove the string requirement and simply accept any method and then your code will work:
static void Main(string[] args)
{
WaitUntilElementVisible(() => PanelHandler("in"));
}
public static void WaitUntilElementVisible(Action preAction = null)
{
preAction?.Invoke();
}
public static void PanelHandler(string className)
{
Console.WriteLine(className);
}
Now of course, you are simply telling the compiler to invoke whichever method is referenced by your action delegate.
Another option is to use a dynamically typed language such as Python ;-)
def waitUntilElementVisible(preAction = None):
if preAction is not None:
preAction()
def panelHandler(className):
print(className)
if __name__=='__main__':
waitUntilElementVisible(panelHandler('in'))
In this case this will work because references are resolved at run-time and not at compile time like in .NET.
The problem is due to your declaration of WaitUntilElementVisible, the declaration
public static void WaitUntilElementVisible(Action<string> preAction = null)
declares a delegate that will take a string parameter, that is, it is expecting that the call to WaitUntilElementVisible will look like:
WaitUntilElementVisible(someString => PanelHandler(someString));
Which would be the useful in the situation where the WaitUntilElementVisible was to provide the string to your delegate.
What you want is for the declaration of WaitUntilElementVisible to be
public static void WaitUntilElementVisible(Action preAction = null)
Which means that it expects a delegate that takes no arguments.

Converting Expression<Func<BaseType,object>> to Expression<Func<DerievedType,object>>>

I have a situation where in, I would like to convert an Expression<Func<BaseType,object>> to Expression<Func<DerievedType,object>>
I am also open to other solutions as well for this particular scenario.
To demonstrate the problem, i have base class as following
public class PersonBase
{
public string Name{get;set;}
public virtual void Save()
{
Dummy.Method1(this,x=>x.Name);
}
}
Derieved Class is defined as
public class Student:PersonBase
{
public string School{get;set;}
}
The Dummy class and associated methods are defined as
public class Dummy
{
public static void Method1<TDestination>(TDestination value,params Expression<Func<TDestination,object>>[] selector)
{
var destinationType = value.GetType();
var selectorType = selector.GetType();
Console.WriteLine("Destination Type : " + destinationType.ToString());
Console.WriteLine("Selector Type : " +selectorType.ToString());
var FinalMethodToCallInfo = typeof(Dummy).GetMethod("FinalMethodToCall", BindingFlags.Public | BindingFlags.Static);
var FinalMethodToCallMethod = FinalMethodToCallInfo.MakeGenericMethod(destinationType);
FinalMethodToCallMethod.Invoke(null, new object[] { selector });
}
public static void FinalMethodToCall<TDestination>(params Expression<Func<TDestination,object>>[] selector)
{
Console.WriteLine("Finally here");
}
}
The whole example is demonstrated in the Fiddle here.
Since the destinationType in Method1 is of Type Student and selectorType is of type Expression>, I get an exception when i attempt to invoke the FinalMethodToCall using reflection.
Object of type 'System.Linq.Expressions.Expression`1[System.Func`2[PersonBase,System.Object]][]' cannot be converted to type 'System.Linq.Expressions.Expression`1[System.Func`2[Student,System.Object]][]'.
I am slightly lost here. One solution I could think of was to use ExpressionVisitor to replace the Expression Parameter Type from BaseClass to DerievedType.
But I was curious to know why, when calling the method from Base (and passing expression), I was pointing to two different types (Derieved and Base). Could someone guide me in understanding this behavior and also if there is a better solution than using ExpressionVisitor to replace the Parameter Type ?
PS: I cannot change signature of my Save Method.
I have made few changes to generic methods as below.
Update PersonBase and make Save method to explicitly declare T.
public class PersonBase
{
public string Name{get;set;}
public virtual void Save<T>() where T : PersonBase
{
Dummy.Method1<T>(this,x=>x.Name);
}
}
Update Method1's first parameter to be Object like below.
public static void Method1<TDestination>(Object value,params Expression<Func<TDestination,object>>[] selector)
And call your Save with explicitly passing generic value like as follow.
(new Student{Name="anu"}).Save<Student>();

C# methods with variable paramterlist as parameter

Hi I'm currently trying to pass methods (with no return value) as parameters to another method (so that they can be called from within the methods).
The problem I'm currently having is, that I'm using Action in the parameterlist and thus need to exactly define which parameters this method takes.
The question thus is: Is there any way to omit this? Thus that I don't have to define which parameters exactly the method has in the parameterdeclaration?
Codeexample:
public void A(int myint)
{
Console.WriteLine(myint.ToString());
}
public void B(int myint1, int myint2)
{
Console.WriteLine((myint1 + myint2).ToString());
}
public void myQuestionMethod(Action<int> parameterMethod)
{
//....Dosomething special by creating the parameters within and calling the given methods
}
myQuestionMethod(A);
myQuestionMethod(B);
Thus Aciton parameterMethod can that be replaced by something else that allows me to give methods as parameters who have differing parameters?
Edit:
I forgot to mention that the TYPE of the parameters is also not fixated.
Thus a function C could exist with (int param1, String param2)
No. There is no way to do this with the Action delegate (that's why there are 16 overloads).
You could opt, if the variables are all of the same type and have the same meaning, to create an array of integers:
public void A(params int[] myint)
{
}
public void myQuestionMethod(Action<int[]> parameterMethod)
{
//....Dosomething special by creating the parameters within and calling the given methods
}
Depending on how big your methods are, you could go for just Action and use anonymous methods rather than explicitly defining the functions
public void myQuestionMethod(Action parameterMethod)
{
//
}
...
myQuestionMethod(() => Console.WriteLine(myInt.ToString()));
myQuestionMethod(() => Console.WriteLine((myInt1 + myInt2).ToString()));
One solution would be to use reflection. Of course don't use it unless you do not have any other choice (specifying a method using its name should be avoided if possible):
public class Foo
{
public void A(int myint)
{
Console.WriteLine(myint.ToString());
}
public void B(int myint1, int myint2)
{
Console.WriteLine((myint1 + myint2).ToString());
}
public void myQuestionMethod(string parameterMethodName, params object[] parameters)
{
var method = this.GetType().GetMethod(parameterMethodName, BindingFlags.Instance | BindingFlags.Public);
method.Invoke(this, parameters);
}
}
public class Test
{
public static void Main()
{
var foo = new Foo();
foo.myQuestionMethod("B", 1, 2);
Console.Read();
}
}

Get MethodInfo for any method with any signature (delegate for any signature)

I want to write a method that will analyze custom attributes of any method (with any number of arguments and any return type) knowing only method info.
This function will check if method has specific Attribute. like this: var tmp = methodInfo.GetCustomAttributes(typeof(LineItemAttribute),false); and if it has such attribute It will execute it.And I want to make call of that function really easy to use. So, in example there are three methods and method GetMethodAttributes that I want to call.
class Test
{
public static void Main()
{
}
public void Test1(){}
public void Test2(int a){}
public void Test3(object a, string c, Boolean d);
public void GetMethodAttributes(MethodInfo mi) {}
}
Ideally I want to write something like that
public static void Main()
{
var t = new Test();
GetMethodAttributes(t.Test1);
GetMethodAttributes(t.Test2);
GetMethodAttributes(t.Test3);
}
I don't want to use string representation of the method names as method names may change, like that:
MethodInfo info = type.GetMethod(name);
Do I have any options? Basically I need a way to use delegates for functions with different sinatures
As Chris Sinclair pointed out in the comment above; you can use a delegate without using reflection or expression trees to get the MethodInfo. The downside is that the compiler is not able to infer the generic parameter so you have to specify the delegate type to match the signature of the given method like this:
public class Test
{
public static void Main()
{
var t = new Test();
CheckMethodAttributes<Action>(t.Test1);
CheckMethodAttributes<Action<int>>(t.Test2);
CheckMethodAttributes<Action<object, string, bool>>(t.Test3);
}
public void Test1() { }
public void Test2(int a) { }
public void Test3(object a, string c, bool d) { }
public static void CheckMethodAttributes<T>(T func)
{
MethodInfo method = new MethodOf<T>(func);
// Example attribute check:
var ignoreAttribute = method.GetAttribute<IgnoreAttribute>();
if (ignoreAttribute != null)
{
// Do something here...
}
}
}
This uses two utility classes, the MethodOf<T> for extracting the MethodInfo from the given Delegate and some AttributeUtils to get strongly typed custom attribute retrieval:
public static class AttributeUtils
{
public static bool HasAttribute<TAttribute>(this MemberInfo member, bool inherit = true)
where TAttribute : Attribute
{
return member.IsDefined(typeof(TAttribute), inherit);
}
public static TAttribute GetAttribute<TAttribute>(this MemberInfo member, bool inherit = true)
where TAttribute : Attribute
{
return member.GetAttributes<TAttribute>(inherit).FirstOrDefault();
}
public static IEnumerable<TAttribute> GetAttributes<TAttribute>(this MemberInfo member, bool inherit = true)
where TAttribute : Attribute
{
return member.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>();
}
}
public class MethodOf<T>
{
public MethodOf(T func)
{
var del = func as Delegate;
if (del == null) throw new ArgumentException("Cannot convert func to Delegate.", "func");
Method = del.Method;
}
private MethodInfo Method { get; set; }
public static implicit operator MethodOf<T>(T func)
{
return new MethodOf<T>(func);
}
public static implicit operator MethodInfo(MethodOf<T> methodOf)
{
return methodOf.Method;
}
}
You can do something like this using Expression Trees, where you pass the method via a lambda expression. You do still need to pass stub values for the parameters, however. For a good example of this in action, check out the source code for Moq, which uses this pattern extensively for setting up mock behaviors for unit testing. Just note that this is not a trivial thing to set up. If you need something relatively quick and dirty, your best bet is probably string names with a good refactoring tool and/or automated tests to help deal with the renaming issues.

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

Say I have a base class TestBase where I define a virtual method TestMe()
class TestBase
{
public virtual bool TestMe() { }
}
Now I inherit this class:
class Test1 : TestBase
{
public override bool TestMe() {}
}
Now, using Reflection, I need to find if the method TestMe has been overriden in child class - is it possible?
What I need it for - I am writing a designer visualizer for type "object" to show the whole hierarchy of inheritance and also show which virtual methods were overridden at which level.
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
I was unable to get Ken Beckett's proposed solution to work. Here's what I settled on:
public static bool IsOverride(MethodInfo m) {
return m.GetBaseDefinition().DeclaringType != m.DeclaringType;
}
There are tests in the gist.
As #CiprianBortos pointed out, the accepted answer is not complete and will lead to a nasty bug in your code if you use it as-is.
His comment provides the magic solution GetBaseDefinition(), but there's no need to check the DeclaringType if you want a general-purpose IsOverride check (which I think was the point of this question), just methodInfo.GetBaseDefinition() != methodInfo.
Or, provided as an extension method on MethodInfo, I think this will do the trick:
public static class MethodInfoUtil
{
public static bool IsOverride(this MethodInfo methodInfo)
{
return (methodInfo.GetBaseDefinition() != methodInfo);
}
}
A simple solution which will also work for protected member and properties is as follows:
var isDerived = typeof(Test1 ).GetMember("TestMe",
BindingFlags.NonPublic
| BindingFlags.Instance
| BindingFlags.DeclaredOnly).Length == 0;
This is a repost of my answer here, which in turn had made references to this question.
A method that also works in some non trivial cases:
public bool Overrides(MethodInfo baseMethod, Type type)
{
if(baseMethod==null)
throw new ArgumentNullException("baseMethod");
if(type==null)
throw new ArgumentNullException("type");
if(!type.IsSubclassOf(baseMethod.ReflectedType))
throw new ArgumentException(string.Format("Type must be subtype of {0}",baseMethod.DeclaringType));
while(type!=baseMethod.ReflectedType)
{
var methods=type.GetMethods(BindingFlags.Instance|
BindingFlags.DeclaredOnly|
BindingFlags.Public|
BindingFlags.NonPublic);
if(methods.Any(m=>m.GetBaseDefinition()==baseMethod))
return true;
type=type.BaseType;
}
return false;
}
And a few ugly tests:
public bool OverridesObjectEquals(Type type)
{
var baseMethod=typeof(object).GetMethod("Equals", new Type[]{typeof(object)});
return Overrides(baseMethod,type);
}
void Main()
{
(OverridesObjectEquals(typeof(List<int>))==false).Dump();
(OverridesObjectEquals(typeof(string))==true).Dump();
(OverridesObjectEquals(typeof(Hider))==false).Dump();
(OverridesObjectEquals(typeof(HiderOverrider))==false).Dump();
(OverridesObjectEquals(typeof(Overrider))==true).Dump();
(OverridesObjectEquals(typeof(OverriderHider))==true).Dump();
(OverridesObjectEquals(typeof(OverriderNothing))==true).Dump();
}
class Hider
{
public virtual new bool Equals(object o)
{
throw new NotSupportedException();
}
}
class HiderOverrider:Hider
{
public override bool Equals(object o)
{
throw new NotSupportedException();
}
}
class Overrider
{
public override bool Equals(object o)
{
throw new NotSupportedException();
}
}
class OverriderHider:Overrider
{
public new bool Equals(object o)
{
throw new NotSupportedException();
}
}
class OverriderNothing:Overrider
{
}
According to this answer there could also be a simple way to check if a virtual method was overridden without to know the exact derived or base type using a test for the MethodAttributes.NewSlot attribute:
public static bool HasOverride(this MethodInfo method)
{
return (method.Attributes & MethodAttributes.Virtual) != 0 &&
(method.Attributes & MethodAttributes.NewSlot) == 0;
}
Together with another extension method
private const BindingFlags Flags = BindingFlags.NonPublic |
BindingFlags.Public | BindingFlags.Instance;
public static bool HasOverride(this Type type, string name, params Type[] argTypes)
{
MethodInfo method = type.GetMethod(name, Flags, null, CallingConventions.HasThis,
argTypes, new ParameterModifier[0]);
return method != null && method.HasOverride();
}
you could then simply call
bool hasOverride = GetType().HasOverride(nameof(MyMethod), typeof(Param1Type),
typeof(Param2Type), ...);
to check if MyMethod is overridden in a derived class.
As far as I've tested this, it seemed to work fine (on my machineā„¢).
There is a better, safer and faster way to do it.
This technique makes sense if your class instance is going to have a long life and the IsOverridden check must be performed several times.
To solve this problem we can use a cache and C# delegates, much faster than reflection!
// Author: Salvatore Previti - 2011.
/// <summary>We need a delegate type to our method to make this technique works.</summary>
delegate int MyMethodDelegate(string parameter);
/// <summary>An enum used to mark cache status for IsOverridden.</summary>
enum OverriddenCacheStatus
{
Unknown,
NotOverridden,
Overridden
}
public class MyClassBase
{
/// <summary>Cache for IsMyMethodOverridden.</summary>
private volatile OverriddenCacheStatus pMyMethodOverridden;
public MyClassBase()
{
// Look mom, no overhead in the constructor!
}
/// <summary>
/// Returns true if method MyMethod is overridden; False if not.
/// We have an overhead the first time this function is called, but the
/// overhead is a lot less than using reflection alone. After the first time
/// this function is called, the operation is really fast! Yeah!
/// This technique works better if IsMyMethodOverridden() should
/// be called several times on the same object.
/// </summary>
public bool IsMyMethodOverridden()
{
OverriddenCacheStatus v = this.pMyMethodOverridden;
switch (v)
{
case OverriddenCacheStatus.NotOverridden:
return false; // Value is cached! Faaast!
case OverriddenCacheStatus.Overridden:
return true; // Value is cached! Faaast!
}
// We must rebuild cache.
// We use a delegate: also if this operation allocates a temporary object
// it is a lot faster than using reflection!
// Due to "limitations" in C# compiler, we need the type of the delegate!
MyMethodDelegate md = this.MyMethod;
if (md.Method.DeclaringType == typeof(MyClassBase))
{
this.pMyMethodOverridden = OverriddenCacheStatus.NotOverridden;
return false;
}
this.pMyMethodOverridden = OverriddenCacheStatus.Overridden;
return true;
}
/// <summary>Our overridable method. Can be any kind of visibility.</summary>
protected virtual int MyMethod(string parameter)
{
// Default implementation
return 1980;
}
/// <summary>Demo function that calls our method and print some stuff.</summary>
public void DemoMethod()
{
Console.WriteLine(this.GetType().Name + " result:" + this.MyMethod("x") + " overridden:" + this.IsMyMethodOverridden());
}
}
public class ClassSecond :
MyClassBase
{
}
public class COverridden :
MyClassBase
{
protected override int MyMethod(string parameter)
{
return 2011;
}
}
class Program
{
static void Main(string[] args)
{
MyClassBase a = new MyClassBase();
a.DemoMethod();
a = new ClassSecond();
a.DemoMethod();
a = new COverridden();
a.DemoMethod();
Console.ReadLine();
}
}
When you run this program as a console application, it will print:
MyClassBase result:1980 overridden:False
ClassSecond result:1980 overridden:False
COverridden result:2011 overridden:True
Tested with Visual Studio 2010, C# 4.0.
Should work also on previous versions, but it can be a little slower on C# less than 3.0 due to optimizations to delegates in the new releases, tests about this would be appreciated :)
However it will be still faster than using reflection!
public static bool HasOverridingMethod(this Type type, MethodInfo baseMethod) {
return type.GetOverridingMethod( baseMethod ) != null;
}
public static MethodInfo GetOverridingMethod(this Type type, MethodInfo baseMethod) {
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod;
return type.GetMethods( flags ).FirstOrDefault( i => baseMethod.IsBaseMethodOf( i ) );
}
private static bool IsBaseMethodOf(this MethodInfo baseMethod, MethodInfo method) {
return baseMethod.DeclaringType != method.DeclaringType && baseMethod == method.GetBaseDefinition();
}
Simple 1-liner based on this and this answers:
typeof(T).GetMember(nameof("Method")).OfType<MethodInfo>()
.Where(m => m.GetBaseDefinition().DeclaringType != m.DeclaringType);

Categories