How to create method interface with variable parameters / different method signatures?

24,874

Solution 1

Replace your args lists with objects that implement a related interface:

public interface IViewModel
{
    //...
    void ResetReferences(IResetValues vals); 
}

I should add that, IMO, ResetReferences() should not take an argument... it should reset to some default value that would be specific to the individual type(s) that implement your interface..."Reset" being the word that means, to me, "restore to initial state"...adding args implies that you can control that.

Solution 2

The purpose of an interface is to have client code know about the interface and be oblivious of the implementation. If your implementations require special treatment when called, the client code need to know what implementation it is calling and then the whole purpose of the interface is lost.

Unless I misunderstand totally what you're trying to accomplish, you're down the wrong road.

Solution 3

If the parameters can be different, then it isn't really a common interface. Put it this way: does the caller need to know the implementation class? If so, you've lost the loose coupling benefits of interfaces.

One option is to encapsulate the parameters into another type, and make the class generic on that type. For example:

public interface IViewModel<T>
{
    void ResetReferences(T data);
}

Then you'd encapsulate the List<Color> colors, List<Size> sizes into one type, and possibly put List<StateProvinces> stateProvinces in another.

It's somewhat awkward though...

Share:
24,874

Related videos on Youtube

Raymond
Author by

Raymond

Updated on October 27, 2020

Comments

  • Raymond
    Raymond over 3 years

    I'm trying to create an interface to a common class, but the implementation classes can have different parameters.

    e.g.

    public interface IViewModel
    {
        //...
        void ResetReferences(); 
    }
    
    // and then, in my class implementations, something like this:
    public class LocationViewModel : IViewModel
    {
        public void ResetReferences(List<StateProvinces> stateProvinces) //...
    }
    
    public class ProductViewModel : IViewModel
    {
        public void ResetReferences(List<Color> colors, List<Size> sizes) //...
    }
    

    So notice that I want to standardize on the ResetReferences naming convention. I'm pretty sure I can't do this, but is there a design pattern that could work? e.g. in my interface, something like below?

    // variable parameters
    void ResetReferences(params object[] list); 
    

    But then how do I make I do type checking or having it call the actual method signature that I want, etc?

    Maybe an interface is the wrong thing to use? Maybe just a base class and some coding conventions?

    Thanks,

  • Raymond
    Raymond almost 13 years
    I like your approach, thank you. BTW, I've renamed the method to "SetReferences" :)
  • Raymond
    Raymond almost 13 years
    Yes, I think you are correct. I'm putting the logic in the wrong place. (This is an MVC application, so I've put the ResetReferences in the Controller class instead of the ViewModel class now).
  • Anders Abel
    Anders Abel almost 13 years
    @Raymond: If you like this answer upvote it and give JeffSahol 10 more reputation points. People appreciate a "thank you" comment, but in the great hunt for reputation a comment won't help.
  • Ejaz
    Ejaz about 8 years
    That's absolutely right. Having hidden away functionality in implementing class takes away a lot of value from interface since the interface doesn't completely define what the implementing classes are going to do.
  • arkon
    arkon almost 8 years
    "It's somewhat awkward though..." What is the most desirable way to approach this problem?
  • Jon Skeet
    Jon Skeet almost 8 years
    @b1nary.atr0phy: Ideally "don't get yourself in this situation". I've given the best answer I could given the limited information - it's very context-sensitive.
  • Joey.Z
    Joey.Z over 6 years
    I don't think you can do anything generic in the implementation of ResetReferences(T data), T has no common interface to act on.
  • Jon Skeet
    Jon Skeet over 6 years
    @zoujyjs: But the implementation doesn't have to be generic - it could be specific to one type. It's not the method that's generic - it's the interface. So someone could implement IViewModel<Foo> and they only need to know what to do with Foo.
  • dns_nx
    dns_nx over 3 years
    That is no good solution, because it violates the interface segregation principle (ISP) of the SOLID principle: a class must not have to implement any interface element that is not required by the particular class!