开发者

Implementing few methods of a interface class-C#

Is it possible in C# to have a class that implement an interface that has 10 methods declared but implementing only 5 methods i.e defining only 5 methods of that interface??? Actually I have an interface that is implemented by 3 class and not all the methods are used by all the class so if I could exclude any method???

I have a need for this. It might sound as a bad design but it's not hopefully. The thing is I have a collection of User Controls that needs to have common property and based on that only I am displaying them at run time. As it's dynamic I need to manage them for that I'm having Properties. Some Properties are needed by few class and not by all. And as the control increases this Properties might be incr开发者_Go百科easing so as needed by one control I need to have in all without any use. just the dummy methods. For the same I thought if there is a way to avoid those methods in rest of the class it would be great. It sounds that there is no way other than having either the abstract class or dummy functions :-(


You can make it an abstract class and add the methods you don't want to implement as abstract methods.

In other words:

public interface IMyInterface
{
    void SomeMethod();
    void SomeOtherMethod();
}

public abstract class MyClass : IMyInterface
{
    // Really implementing this
    public void SomeMethod()
    {
        // ...
    }

    // Derived class must implement this
    public abstract void SomeOtherMethod();
}

If these classes all need to be concrete, not abstract, then you'll have to throw a NotImplementedException/NotSupportedException from inside the methods. But a much better idea would be to split up the interface so that implementing classes don't have to do this.

Keep in mind that classes can implement multiple interfaces, so if some classes have some of the functionality but not all, then you want to have more granular interfaces:

public interface IFoo
{
    void FooMethod();
}

public interface IBar()
{
    void BarMethod();
}

public class SmallClass : IFoo
{
    public void FooMethod() { ... }
}

public class BigClass : IFoo, IBar
{
    public void FooMethod() { ... }
    public void BarMethod() { ... }
}

This is probably the design you really should have.


Your breaking the use of interfaces. You should have for each common behaviour a seperate interface.


That is not possible. But what you can do is throw NotSupportedException or NotImplementedException for the methods you do not want to implement. Or you could use an abstract class instead of an interface. That way you could provide a default implementation for methods you choose not to override.

public interface IMyInterface
{
  void Foo();

  void Bar();
}

public class MyClass : IMyInterface
{
  public void Foo()
  {
    Console.WriteLine("Foo");
  }

  public void Bar()
  {
    throw new NotSupportedException();
  }
}

Or...

public abstract class MyBaseClass
{
  public virtual void Foo()
  {
    Console.WriteLine("MyBaseClass.Foo");
  }

  public virtual void Bar()
  {
    throw new NotImplementedException();
  }
}

public class MyClass : MyBaseClass
{
  public override void Foo()
  {
    Console.WriteLine("MyClass.Foo");
  }
}


While I agree with @PoweRoy, you probably need to break your interface up into smaller parts you can probably use explicit interfaces to provider a cleaner public API to your interface implementations.

Eg:

public interface IPet
{
   void Scratch();
   void Bark();
   void Meow();
}

public class Cat : IPet
{
    public void Scratch()
    {
        Console.WriteLine("Wreck furniture!");
    }

    public void Meow()
    {
       Console.WriteLine("Mew mew mew!");
    }

    void IPet.Bark()
    {
        throw NotSupportedException("Cats don't bark!");
    }
}

public class Dog : IPet
{
    public void Scratch()
    {
        Console.WriteLine("Wreck furniture!");
    }

    void IPet.Meow()
    {
       throw new NotSupportedException("Dogs don't meow!");
    }

    public void Bark()
    {
        Console.WriteLine("Woof! Woof!");
    }
}

With the classes defined above:

var cat = new Cat();
cat.Scrach();
cat.Meow();
cat.Bark(); // Does not compile


var dog = new Dog();
dog.Scratch();
dog.Bark();
dog.Meow(); // Does not compile.


IPet pet = new Dog();
pet.Scratch();
pet.Bark();
pet.Meow(); // Compiles but throws a NotSupportedException at runtime.

// Note that the following also compiles but will
// throw NotSupportedException at runtime.
((IPet)cat).Bark();
((IPet)dog).Meow();


You can simply have the methods you don't want to impliment trow a 'NotImplementedException'. That way you can still impliment the interface as normal.


No, it isn't. You have to define all methods of the interface, but you are allowed to define them as abstract and leave the implementation to any derived class. You can't compile a class that says that implements an interface when in fact it doesn't.


Here is a simple stupid example of what I meant by different interfaces for different purposes. There is no interface for common properties as it would complicate example. Also this code lacks of many other good stuff (like suspend layout) to make it more clear. I haven't tried to compile this code so there might be a lot of typos but I hope that idea is clear.

interface IConfigurableVisibilityControl
{
    //check box that controls whether current control is visible
    CheckBox VisibleCheckBox {get;}
}


class MySuperDuperUserControl : UserControl, IConfigurableVisibilityControl
{
    private readonly CheckBox _visibleCheckBox = new CheckBox();

    public CheckBox VisibleCheckBox 
    {
        get { return _visibleCheckBox; }
    }
    //other important stuff
}

//somewhere else
void BuildSomeUi(Form f, ICollection<UserControl> controls)
{
    //Add "configuration" controls to special panel somewhere on the form
    Panel configurationPanel = new Panel();
    Panel mainPanel = new Panel();
    //do some other lay out stuff
    f.Add(configurationPanel);
    f.Add(mainPanel);

    foreach(UserControl c in controls) 
    {
        //check whether control is configurable
        IConfigurableOptionalControl configurableControl = c as IConfigurableVisibilityControl;
        if(null != configurableControl) 
        {
            CheckBox visibleConfigCB = configurableControl.VisibleCheckBox;
            //do some other lay out stuff
            configurationPanel.Add(visibleConfigCB);
        }
        //do some other lay out stuff
        mainPanel.Add(c);
    }
}


Let your Interface be implemented in an abstract class. The abstract class will implement 5 methods and keep remaining methods as virtual. All your 3 classes then should inherit from the abstract class. This was your client-code that uses 3 classes won't have to change.


I want to add dynamically the control to my form as I have that as my requirement. I found the code from here. I edited it as I needed. So I have the IService class that has the common properties. This is implemented by the User Controls. Which are shown at runtime in different project. Hmmm for that I have different common interface that has properties which are used by the project for displaying the controls. Few controls need some extra methods or peoperties for instance to implement a context menu based on user selection at runtime. i.e the values are there in the project which will be passed as the properties to the control and it will be displayed. Now this menu is there only for one control rest of them don't have this. So I thought if there is a way to not to have those methods in all class rather than one class. But it sounds that I need to either go for dummy methods or abstract class. hmmm dummy methods would be more preferable to me than the abstract class :-(


By implementing one of the SOLID principle which is "Interface Segregation Principle" in which Interface is broken into mutiple interfaces.


Apart from the above excellent suggestions on designing interfaces, if you really need to have implementation of some of the methods,an option is to use 'Extension methods'. Move the methods that need implementation outside of your interface. Create another static class that implements these as static methods with the first parameter as 'this interfaceObject'. This is similar to extension methods used in LINQ for IEnumerable interface.

public static class myExtension {
    public static void myMethod( this ImyInterface obj, ... ) { .. }
...
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜