13

Is this possible without reflection otherwise with reflection ? This is something very often used in PHP like in Wordpress.

Something in pseudo code:

if (exists(object.method)) {object.method}

or

try {object.method} finally {...}
10
  • What do you mean by "only if it exists?" Commented Jan 31, 2011 at 22:01
  • 1
    Even with reflection, you would have to take the method's prototype into account: int Foo(string bar) is not the same as double Foo(int bar, IDictionary<int, string> quux). Commented Jan 31, 2011 at 22:03
  • 1
    Are you looking for partial methods? msdn.microsoft.com/en-us/library/6b0scde8.aspx
    – Ani
    Commented Jan 31, 2011 at 22:04
  • Check for null your MethodInfo object Commented Jan 31, 2011 at 22:04
  • 2
    @AndrewGrimm even with null-propagating operator you would have gotten a compile time error. All the provided answers still hold true to today. So I find the out-of-date statement to not hold merit
    – Nkosi
    Commented Oct 1, 2019 at 2:38

6 Answers 6

23

Well, you could declare it in an interface, and then use:

IFoo foo = bar as IFoo;
if (foo != null)
{
    foo.MethodInInterface();
}

That assumes you can make the object's actual type implement the interface though.

Otherwise you'd need to use reflection AFAIK.

(EDIT: The dynamic typing mentioned elsewhere would work on .NET 4 too, of course... but catching an exception for this is pretty nasty IMO.)

3
  • A possible performance optimization if this isn't possible would be to use reflection once, and generate a dynamic method to optimize future calls.
    – user541686
    Commented Jan 31, 2011 at 22:07
  • Too heavy in the context I want to use: it's about for 50 methods if I had to create an interface for each single method ...
    – user310291
    Commented Jan 31, 2011 at 22:09
  • This would be the .net way of doing this. The reflection answer is also a reasonable way of doing this, but carries a significant performance hit compared to using an Interface. PHP does allow dynamic methods like this, but I agree with user166390, this falls in the category of trying to shoehorn a feature of a different language into another. The dynamic method also "works" but I would agree, this seems very kludgy and would carry a performance hit as well.
    – Kelmar
    Commented Oct 12, 2016 at 19:46
17

You could use dynamics and catch the Runtime exception:

dynamic d = 5;
try
{
    Console.WriteLine(d.FakeMethod(4));
}
catch(RuntimeBinderException)
{
    Console.WriteLine("Method doesn't exist");
}

Although it sounds more like a design problem.

Disclaimer
This code is not for use, just an example that it can be done.

6
  • 15
    Using exceptions for flow control is nasty, Nasty, NASTY.
    – jason
    Commented Jan 31, 2011 at 22:17
  • 4
    As Jason says, this will be nasty - and the performance hit could be pretty big as well, if you're doing this a lot.
    – Jon Skeet
    Commented Jan 31, 2011 at 22:19
  • 2
    @user310291: Yeah, it's what you want in the same way that your physician solving your carpal tunnel syndrome by chopping your arms off is what you want.
    – jason
    Commented Jan 31, 2011 at 22:26
  • 1
    If you guys think the educational purpose of this code isn't worth seeing it in someone's code, I can delete it. Commented Jan 31, 2011 at 22:39
  • 5
    This is why I'm always so critical of SO. You answer a question as-written and you get nothing but griping and moaning in response. In a good many cases, there is NOTHING wrong with this code. Not everything is RT code for the space shuttle. Oftentimes, things take a second or three and it's FINE. Commented Nov 17, 2015 at 18:40
14
+25

Use .GetType().GetMethod() to check if it exists, and then .Invoke() it.

var fooBar = new FooBarClass();
var method = fooBar.GetType().GetMethod("ExistingOrNonExistingMethod");
if (method != null)
{
    method.Invoke(fooBar, new object[0]);
}
1
  • 1
    I would personally use this example if I wanted to either avoid dynamic, or I didn't maintain the source of FooBarClass and knew it could change in the future to no longer include the method I am looking for.
    – Jimenemex
    Commented Oct 7, 2019 at 18:08
6

With the dynamic type in C# 4.0, you could do something like this:

dynamic obj = GetDynamicObject();
if (obj != null && obj.GetType().GetMethod("DoSomething") != null)
{
    obj.DoSomething();
}

But the only way to tell if a type has a method in the first place is to use reflection; so the above approach doesn't really buy you anything (you might as well take the MethodInfo you get from calling GetMethod and just Invoke it).

Edit: If you're open to trying to call the method even when it's not there, then Yuriy's answer is probably what you're looking for. My original answer was a literal response to the way you worded your question: "How to call a C# method only if it exists."

3

I came across this looking for the same answer but did not like any of the solutions.

here is mine:

//Invoke the refresh method if the datasource contains it
if (this.DataSource.GetType().GetMethod("Refresh") != null)
     this.DataSource.GetType().GetMethod("Refresh").Invoke(this.DataSource, new object[] { });
2

You should revise existance first. MethodInfo[] myArrayMethodInfo = myType.GetMethods();

Not the answer you're looking for? Browse other questions tagged or ask your own question.