Подтвердить что ты не робот

Внедрение нескольких методов интерфейса class-С#

Возможно ли в С# иметь класс, реализующий интерфейс, который имеет 10 объявленных методов, но реализующий только 5 методов, определяющих только 5 методов этого интерфейса? На самом деле у меня есть интерфейс, который реализуется 3-м классом, и не все методы используются всем классом, поэтому, если бы я мог исключить любой метод???

Мне нужно это. Это может показаться плохим дизайном, но это не так. Дело в том, что у меня есть коллекция пользовательских элементов управления, которые должны иметь общее свойство и на основе этого только я показываю их во время выполнения. Поскольку это динамическое, мне нужно управлять ими, потому что у меня есть Свойства. Некоторые свойства необходимы нескольким классам, а не всем. И по мере увеличения контроля этот Свойства может увеличиваться по мере необходимости одним элементом управления, который я должен использовать без использования. просто фиктивные методы. Для того же я думал, что если есть способ избежать этих методов в остальном классе, это было бы здорово. Похоже, что нет другого способа, кроме наличия абстрактного класса или фиктивных функций: - (

4b9b3361

Ответ 1

Вы можете сделать его абстрактным классом и добавить методы, которые вы не хотите применять в качестве абстрактных методов.

Другими словами:

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();
}

Если эти классы должны быть конкретными, а не абстрактными, тогда вам придется бросать NotImplementedException/NotSupportedException из методов. Но гораздо лучшей идеей было бы разделить интерфейс, чтобы реализовать классы не нужно.

Имейте в виду, что классы могут реализовывать несколько интерфейсов, поэтому, если некоторые классы имеют некоторые функции, но не все, то вы хотите иметь более гранулированные интерфейсы:

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() { ... }
}

Это, вероятно, дизайн, который вы действительно должны иметь.

Ответ 2

Прерывание использования интерфейсов. Вы должны иметь для каждого общего поведения отдельный интерфейс.

Ответ 3

Вы можете просто использовать методы, которые вы не хотите внедрять в "NotImplementedException". Таким образом, вы все еще можете внедрить интерфейс как обычно.

Ответ 4

Это невозможно. Но вы можете сделать throw NotSupportedException или NotImplementedException для методов, которые вы не хотите реализовать. Или вы можете использовать абстрактный класс вместо интерфейса. Таким образом, вы могли бы обеспечить реализацию по умолчанию для методов, которые вы предпочитаете не переопределять.

public interface IMyInterface
{
  void Foo();

  void Bar();
}

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

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

Или...

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");
  }
}

Ответ 5

В то время как я согласен с @PoweRoy, вам, вероятно, нужно разбить свой интерфейс на более мелкие части, вы, вероятно, можете использовать явные интерфейсы для провайдера для более чистого публичного API для реализации интерфейса.

Например:

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!");
    }
}

С указанными выше классами:

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();

Ответ 6

Нет, это не так. Вы должны определить все методы интерфейса, но вам разрешено определять их как абстрактные и оставить реализацию в любом производном классе. Вы не можете скомпилировать класс, который говорит, что реализует интерфейс, если на самом деле это не так.

Ответ 7

Вот простой глупый пример того, что я имел в виду под разными интерфейсами для разных целей. Интерфейс для общих свойств отсутствует, так как это будет затруднять пример. Также в этом коде не хватает многих других полезных материалов (например, макета для приостановки), чтобы сделать его более понятным. Я не пытался скомпилировать этот код, поэтому может быть много опечаток, но я надеюсь, что идея понятна.

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);
    }
}

Ответ 8

Пусть ваш интерфейс будет реализован в абстрактном классе. Абстрактный класс будет реализовывать 5 методов и сохранять оставшиеся методы виртуальными. Все ваши 3 класса затем должны наследовать от абстрактного класса. Это ваш клиентский код, который использует 3 класса, не изменится.

Ответ 9

Я хочу добавить динамически элемент управления в мою форму, поскольку у меня есть это как мое требование. Я нашел код здесь. Я отредактировал его так, как мне было нужно. Поэтому у меня есть класс IService, который имеет общие свойства. Это осуществляется с помощью элементов управления пользователя. Которые отображаются во время выполнения в разных проектах. Hmmm для этого у меня есть другой общий интерфейс, который имеет свойства, которые используются проектом для отображения элементов управления. Многим элементам управления необходимы некоторые дополнительные методы или объекты, например, для реализации контекстного меню на основе выбора пользователя во время выполнения. то есть значения в проекте, которые будут переданы в качестве свойств для элемента управления, и он будет отображаться. Теперь это меню доступно только для одного элемента управления, которого у них нет. Поэтому я подумал, что есть способ не иметь эти методы во всех классах, а не в одном классе. Но мне кажется, что мне нужно либо пойти на фиктивные методы, либо на абстрактный класс. методы hmmm dummy были бы более предпочтительны для меня, чем абстрактный класс: - (

Ответ 10

Используя один из принципов SOLID, который является "Принципом разделения интерфейса", в котором интерфейс разбит на несколько интерфейсов.

Ответ 11

Помимо вышеупомянутых превосходных предложений по проектированию интерфейсов, если вам действительно нужно реализовать некоторые из методов, опция заключается в использовании "методов расширения". Переместите методы, которые требуют реализации вне вашего интерфейса. Создайте еще один статический класс, который реализует их как статические методы с первым параметром как "this interfaceObject". Это похоже на методы расширения, используемые в LINQ для интерфейса IEnumerable.

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