Implementación de algunos métodos de una interfaz clase-C#


¿Es posible en C# tener una clase que implemente una interfaz que tenga 10 métodos declarados pero que implemente solo 5 métodos, es decir, que defina solo 5 métodos de esa interfaz??? En realidad tengo una interfaz que se implementa por 3 clase y no todos los métodos son utilizados por toda la clase por lo que si pudiera excluir cualquier método???

Tengo una necesidad de esto. Puede sonar como un mal diseño, pero no es con suerte. La cosa es que tengo una colección de Controles de usuario que necesita tener en común propiedad y basado en eso solo los estoy mostrando en tiempo de ejecución. Como es dinámico, necesito administrarlos para que tenga propiedades. Algunas propiedades son necesarias por pocas clases y no por todos. Y a medida que el control aumenta estas propiedades podrían estar aumentando así que según sea necesario por un control que necesito tener en todos sin ningún uso. sólo los métodos ficticios. Por lo mismo pensé que si hay una manera de evitar esos métodos en el resto de la clase sería genial. Suena que no hay otra manera que que tengan la clase abstracta o funciones ficticias: - (

Author: Jankhana, 2010-04-27

11 answers

Puede convertirla en una clase abstracta y agregar los métodos que no desea implementar como métodos abstractos.

En otras palabras:

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

Si todas estas clases necesitan ser concretas, no abstractas, entonces tendrás que lanzar un NotImplementedException/NotSupportedException desde dentro de los métodos. Pero una idea mucho mejor sería dividir la interfaz para que las clases de implementación no tengan que hacer esto.

Tenga en cuenta que las clases pueden implementar múltiples interfaces, por lo que si algunas clases tienen funcionalidad pero no todas, entonces desea tener interfaces más granulares:

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

Este es probablemente el diseño que realmente deberías tener.

 25
Author: Aaronaught,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 13:21:02

Romper el uso de interfaces. Debe tener para cada comportamiento común una interfaz separada.

 18
Author: RvdK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 13:16:56

Eso no es posible. Pero lo que puede hacer es lanzar NotSupportedException o NotImplementedException para los métodos que no desea implementar. O podría usar una clase abstracta en lugar de una interfaz. De esa manera, podría proporcionar una implementación predeterminada para los métodos que elija no anular.

public interface IMyInterface
{
  void Foo();

  void Bar();
}

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

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

O...

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");
  }
}
 4
Author: Brian Gideon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 13:16:48

Simplemente puede tener los métodos que no desea implementar trow a 'NotImplementedException'. De esa manera todavía se puede implementar la interfaz de forma normal.

 3
Author: UpTheCreek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 13:16:20

Aunque estoy de acuerdo con @PoweRoy, probablemente necesite dividir su interfaz en partes más pequeñas, probablemente pueda usar interfaces explícitas para proporcionar una API pública más limpia a sus implementaciones de interfaz.

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

Con las clases definidas anteriormente:

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();
 3
Author: orj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 13:34:11

No, no lo es. Tiene que definir todos los métodos de la interfaz, pero se le permite definirlos como abstractos y dejar la implementación a cualquier clase derivada. No se puede compilar una clase que dice que implementa una interfaz cuando en realidad no lo hace.

 1
Author: Otávio Décio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 13:17:55

Aquí hay un simple ejemplo estúpido de lo que quise decir con diferentes interfaces para diferentes propósitos. No hay interfaz para las propiedades comunes, ya que complicaría el ejemplo. También este código carece de muchas otras cosas buenas (como suspender el diseño) para hacerlo más claro. No he intentado compilar este código, así que puede haber muchos errores tipográficos, pero espero que la idea esté clara.

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);
    }
}
 1
Author: SergGr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 14:32:42

Deje que su Interfaz se implemente en una clase abstracta. La clase abstract implementará 5 métodos y mantendrá los métodos restantes como virtuales. Todas sus 3 clases entonces deben heredar de la clase abstracta. Este fue su cliente-código que utiliza 3 clases no tendrá que cambiar.

 0
Author: this. __curious_geek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 13:16:53

Quiero agregar dinámicamente el control a mi formulario, ya que lo tengo como requisito. Encontré el código de aquí. Lo edité cuando lo necesitaba. Así que tengo la clase IService que tiene las propiedades comunes. Esto es implementado por los Controles de Usuario. Que se muestran en tiempo de ejecución en diferentes proyectos. Hmmm para eso tengo una interfaz común diferente que tiene propiedades que son utilizadas por el proyecto para mostrar los controles. Pocos controles necesitan algunos métodos o personas adicionales, por ejemplo, para implementar un menú contextual basado en la selección del usuario en tiempo de ejecución. es decir, los valores están allí en el proyecto que se pasarán como las propiedades al control y se mostrará. Ahora este menú está ahí solo para un control el resto de ellos no tienen esto. Así que pensé si hay una manera de no tener esos métodos en todas las clases en lugar de una clase. Pero suena que tengo que ir por métodos ficticios o clase abstracta. hmmm métodos ficticios sería más preferible a mí que el resumen clase :-(

 0
Author: Jankhana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 13:58:10

Implementando uno de los principios SÓLIDOS que es el "Principio de Segregación de Interfaz" en el que la interfaz se divide en múltiples interfaces.

 0
Author: hammad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-30 10:24:21

Aparte de las excelentes sugerencias anteriores sobre el diseño de interfaces, si realmente necesita tener implementación de algunos de los métodos,una opción es usar 'Métodos de extensión'. Mueva los métodos que necesitan implementación fuera de su interfaz. Cree otra clase estática que implemente estos como métodos estáticos con el primer parámetro como 'this interfaceObject'. Esto es similar a los métodos de extensión utilizados en LINQ para la interfazerableumerable.

public static class myExtension {
    public static void myMethod( this ImyInterface obj, ... ) { .. }
...
}
 0
Author: shr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-27 06:53:30