tags:

views:

322

answers:

12

I have an object that implements an interface. I want to call on the object's method if it is implemented. What's the best way in doing this?

Update A few of you mentioned that my question was vague. Sorry about that. When i said "if it is implemented" i meant "if it is callable". Thanks for your answers and effort guys (or girls!). I'm amazed how much developer support there is on this website.

+12  A: 

Not quite sure what you mean by "if it is implemented." If the method is in the interface and your object implements the interface it must implement the method.

Jason Punyon
There must be an implementation, but it may very well just throw a NotImplementedException, in fact telling that there isn't really an implementation available... see for instance the `Stream` class in the framework (which is not an interface but an abstract class, but the concept is identical for both).
Lucero
But either way it is still implemented as far as the compiler is concerned, so what is the question?
Ed Swangren
I think that there is a confusion between being implemented (callable in the code) and implemented (logically, e.g. the object supports the operation). My guess is that the author of the question means the latter.
Lucero
If that's the case, then use `NotImplementedException` and catch the exception.
Will Eddins
+2  A: 

Shouldn't the object's class implement every method of the interface?

If the object's class inherits from an abstract class, it is possible that it might not override("implement") some methods. Perhaps you are mixing the two up in your mind.

Mike Atlas
+6  A: 

Create two interfaces, and inherit both interfaces where all methods are required. Inherit only one of the interfaces where the optional methods aren't required. You can also create a base interface, from which all your interface will inherit, for OOP uses.

Am
+9  A: 

If you want to test if an object implements the interface so you can call the method, you can do it like so:

interface IFoo { void Bar(); }

object o = GetObjectThatMayImplementIFoo();
IFoo foo = o as IFoo;

if (foo != null) {
  foo.Bar();
}

I think that's what you were asking?

wojo
Note that the pattern `is` followed by a cast is discouraged, you should use `as` and check for `null` (better performance since the runtime does not perform two typecasts).
Lucero
True, I don't use that myself, not sure why I wrote the example that way. Updated!
wojo
Perfect, +1 for you... ;)
Lucero
+2  A: 

As with the other answers, I'm not sure what you mean. The closest that a class implementing an interface can get to not implementing one of the interface methods is throwing a NotImplementedException. The way to handle this is to specifically catch that exception when calling the method. However, the whole point of an interface is to define a contract between classes, so maybe some clarification would help.

oltman
+1  A: 

You cannot really know if the method is actually implemented (or if the class just has a "dummy" implementation). Therefore, you may use a pattern such as one of the following to find out if a specific method is supported:

-> Have multiple interfaces and see if the class actually implements it; this is probably the cleanest way to deal with it, but it may leave you with a large number of different interfaces, which may not be desirable:

IIntfA = inst as IIntfA;
if (inst != null) {
  // inst seems to be implemented
}

-> Use methods in the TryXxx style, which return true if they were successfull (like TryParse() etc.).

-> Use NotImplementedException - but note that catching those is very expensive and should only be used for calls which are performed rarely, or where a missing implementation is not expected. The Stream class works like this, for instance if it cannot be written to (but additionally there is a property telling what the class supports, e.g. IsWritable in the Stream class).

Lucero
You missed the variable name
Seth Illgard
+2  A: 

My first response is don't do this. It creates conditional logic around the possibility of a method being there, it goes against the statically typeness of C# and breaks a couple of the SOLID principles. My experience tells me this is the wrong path to walk down.

With that said it can be done via Reflection or using the 'is/as' solution wojo demonstrates.

This type of behavior might be better implemented in a dynamic language. It sounds similar to Duck typing. I'm not a dynamic language guy, but if you have unit tests, it may be alright.

Chuck Conway
+3  A: 

If this really the way you need it to work, an interface is the wrong choice. Instead, you could have an abstract class from which your class derives with a virtual method. Virtual allows it to be overridden, but does not require it. Since a virtual method has an implementation, it cannot be part of an interface.

Jim Blake
The child classes will still have a virtual method implementation. It will be the base class implementation.
Chuck Conway
+1  A: 

Hey guys, don't forget the "is" keyword :P

You can check if an object implements an interface like this too:

if (inst is IInterface) 
{
  // you can safely cast it
}

I prefer it that way but of course you could also use the "as" keyword

IInterface a = inst as IInterface;
if (a != null) 
{
  // use a, already casted
}
Seth Illgard
+3  A: 

I think what you're really looking for is a partial method. These are new in .NET 3.5. You simply declare the method as "partial":

partial void OnLoaded();

The method can be called normally:

OnLoaded();

The neat thing is that if the method is not implemented anywhere, the compiler is smart enough not to generate the call.

This was implemented primarily for LINQ to SQL and for Entity Framework; this allows generated code (using partial classes) to define and call methods without knowing whether they are implemented.

Mixing partial methods with interfaces would be interesting (I haven't tried it), but my first try would be declaring a partial method in the interface.

Cylon Cat
+1. This answer is what my intuition came up with, too.
Brian
I doubt that's what he needs. Partial methods are supposed to be used to set up optional "callbacks" between two parts of the same class (where one is typically generated, and other hand-coded). They have a lot of limitations - private only, `void` return, etc. They definitely don't have anything to do with interfaces.
Pavel Minaev
They were certainly created for working with generated code in partial classes. We don't have enough info on the original poster's requirements to know whether this is a good fit. It would also be possible to set up properties as accessors to private methods, so "private" isn't necessarily a drawback. (For that matter, properties might be another approach to the problem.)
Cylon Cat
A: 

I don't know if you might be looking for something like this. This uses an attribute that you can flag a method with whether or not it is implemented. Next I added an extension method to the interface to allow for checking if ithe method is implemented. Finally, the code will allow you to ask an object if the method is implemented. I don't like this but it might be what you are looking for.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    public static class Program
    {
        static void Main(string[] args)
        {
            EmployeeA empA = new EmployeeA();

            if (empA.IsImplemented("TestMethod"))
                empA.TestMethod();

            EmployeeB empB = new EmployeeB();
            if (empB.IsImplemented("TestMethod"))
                empB.TestMethod();


            Console.ReadLine();

        }

        public static bool IsImplemented(this IEmp emp, string methodName)
        {
            ImplementedAttribute impAtt;
            MethodInfo info = emp.GetType().GetMethod(methodName);
            impAtt = Attribute.GetCustomAttribute(info, typeof(ImplementedAttribute), false)
                        as ImplementedAttribute;

            return (impAtt == null) ? true : impAtt.Implemented;

        }

    }

    public class EmployeeA : IEmp
    {
        #region IEmp Members

        [Implemented(false)]
        public void  TestMethod()
        {
            Console.WriteLine("Inside of EmployeeA");
        }

        #endregion
    }

    public class EmployeeB : IEmp
    {
        #region IEmp Members

        [Implemented(true)]
        public void TestMethod()
        {
            Console.WriteLine("Inside of EmployeeB");
        }

        #endregion
    }


    public class ImplementedAttribute : Attribute
    {
        public bool Implemented { get; set; }

        public ImplementedAttribute():this(true)
        {
        }

        public ImplementedAttribute(bool implemented)
        {
            Implemented = implemented;
        }
    }

    public interface IEmp
    {
        void TestMethod();
    }

}

EDIT: After original author reworded question, you definitely just want to implement the interface guranteeing the method does exist. I will leave above code for curiosity sake.

Bomlin
Aww thanks! A very interesting solution.
burnt1ce
A: 

Depending on how you're referencing an object, certain members will be visible. An interface might be implicitly defined or explicitly defined, or might be implemented by a derived class and you're using a base class reference. In other words, it's not always immediately evident all the available members on an object.

So if you want to test for implementation of a certain interface (ISomething) by your object (yourObj), one choice is testing the data type, using reflection. Based on the result of this test, you can explicitly cast an implementing object into the interface Type and use its members...

if (yourObj is ISomething)
     ((ISomething)yourObj).DoSomething();

This is the same thing done another way (more "wordy" using method calls):

if (typeof(ISomething).IsAssignableFrom(yourObj.GetType()))
    ((ISomething)yourObj).DoSomething();

This sample assumes the ISomething interface is defined as:

public interface ISomething {
    void DoSomething();
    // other members ...
}

In summary, this code says: if the interface ISomething Is-Assignable-From your object of choice, then your object implements that interface and therefore has those public members.

John K