tutorial polimorfismo interfaces implement herencia clase abstracta c# interface

polimorfismo - implement interface c#



Getter y setter procedentes de diferentes interfaces. (5)

Realmente necesito tener algo como esto:

interface IReadableVar { object Value { get; } } interface IWritableVar { object Value { set; } } interface IReadableWritableVar : IReadableVar, IWritableVar { }

Sin embargo, cuando intento usar IReadableWritableVar.Value , obtengo errores de compilación a menos que los IReadableWritableVar.Value explícitamente a la interfaz base, como aquí:

static void Main() { IReadableWritableVar var = null; var t = var.Value; // <-- CS0229: Ambiguity between ''IReadableVar.Value'' and ''IWritableVar.Value'' var.Value = null; // <-- CS0229: Ambiguity between ''IReadableVar.Value'' and ''IWritableVar.Value'' var v = ((IReadableVar)var).Value; // compiles fine ((IWritableVar)var).Value = null; // compiles fine }

¿Por qué recibo estos errores aunque todo debe quedar claro para el compilador? ¿Hay alguna forma de solucionar este problema que no sea el lanzamiento (cientos de lugares en la aplicación)?

Actualización: se sugirió que esta es una duplicación de Implementar 2 interfaces con propiedades de "mismo nombre" pero esto es ligeramente diferente, ya que en el otro caso no hay herencia en las interfaces. De todos modos, el problema está resuelto ahora - ver respuesta aceptada.


Bueno, efectivamente, Getter y Setter son solo dos métodos. Cuando usamos la interfaz IReadableWritableVar , existen dos métodos con un nombre idéntico heredado de las interfaces base y el compilador no sabe cuál de estos dos debería usar, por lo tanto, la ambigüedad.

Cuando enviamos eso a una de estas interfaces, el otro miembro desaparece y no hay ningún error.

Si implementamos esos miembros, no habrá ningún error ya que el compilador usará esa implementación:

class ReadableWritableVar : IReadableWritableVar { public object Value { get; set; } } var @var = new ReadableWritableVar(); var t = @var.Value;

También puede usar una implementación de miembros de la interfaz explícita de la respuesta de @Alessandro D''Andria si se requiere que use la interfaz y no la clase.


El uso de la clase abstracta istead of interface resolverá su problema.

public abstract class ReadableWritableVar : IReadableVar, IWritableVar { public object Value { get; set; } }


Interesante pregunta. Creo que los métodos de extensión ayudarán en este caso.

public static class Extension { public static object GetValue(this IReadableVar v) { return v.Value; } public static void SetValue(this IWritableVar v, object value) { v.Value = value; } }

Necesitas cambiar el código para usarlo:

IReadableWritableVar variable = null; var t = variable.GetValue(); variable.SetValue(null);

El método de extensión hace el elenco para usted.


Una posible alternativa es usar métodos explícitos (estilo java) para obtener y establecer en lugar de una propiedad:

interface IReadableVar { object GetValue(); } interface IWritableVar { void SetValue(object value); } interface IReadableWritableVar : IReadableVar, IWritableVar { }

El uso entonces se convierte en:

static void Main(string[] args) { IReadableWritableVar aVar = null; var t = aVar.GetValue(); aVar.SetValue(null); }


Una posible solución puede ser modificar su interfaz IReadableWritableVar siguiente manera:

interface IReadableWritableVar : IReadableVar, IWritableVar { new object Value { get; set; } }

Pero tenga en cuenta que una implementación válida debe ser:

class ReadableWritableVar : IReadableWritableVar { public object Value { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } object IWritableVar.Value { set { throw new NotImplementedException(); } } object IReadableVar.Value { get { throw new NotImplementedException(); } } }

Un ejemplo más concreto:

class ReadableWritableVar : IReadableWritableVar { public object Value { get { return ((IReadableVar)this).Value; } set { ((IWritableVar)this).Value = value; } } object _val; object IWritableVar.Value { set { _val = value; } } object IReadableVar.Value => _val; }

O mejor:

class ReadableWritableVar : IReadableWritableVar { public object Value { get; set; } object IWritableVar.Value { set { Value = value; } } object IReadableVar.Value => Value; }