2010-02-04 10 views
17

Tengo algunas preguntas relacionadas con el diseño de mi clase User pero son lo suficientemente diferentes como para que piensen que deberían ser preguntas independientes.Intentando heredar tres clases base y no puedo

Por lo tanto, el primero está relacionado con la herencia de las clases base. Actualmente estoy heredar dos clases, ProfileBase y ISessionMgrEntry como tal:

public class User : ProfileBase, ISessionMgrEntry 

Pero, también quiero heredar una tercera clase, MembershipUser, así:

public class User : ProfileBase, MembershipUser, ISessionMgrEntry 

Sin embargo, el won compilador' Déjame hacer eso. ¿Por qué? Y, ¿cómo consigo alrededor de esto?

Gracias.

PS - ASP.NET 3.5/C#

EDITAR

Hola. Creo que la solución a continuación puede funcionar para lo que estoy tratando de lograr. Parece bastante simple y directo. Estoy haciendo esto para poder crear un objeto completo/combinado User. ¿Alguien ve alguna razón por la cual esto podría causar problemas? Uno que surgió mientras estaba ding es superposición de propiedades. Por ejemplo, ambos MembershipUser y ProfileBase comparten "UserName". ¿Debo simplemente elegir uno u otro o será un defecto de diseño? Sugerencias? Gracias de nuevo.

public class User 
    { 

     #region Constructors 
      private readonly MembershipUser _MembershipUser; 
      private readonly ProfileBase _ProfileBase; 
     #endregion 

     public User() 
     { 
      _MembershipUser = new MembershipUser(); 
      _ProfileBase = new ProfileBase(); 

     } 

     public string Comment 
     { 
      get { return _MembershipUser.Comment as string; } 
      set { _MembershipUser.Comment = value; } 
     } 

     public bool IsAnonymous 
     { 
      get { return _ProfileBase.IsAnonymous as bool; } 
     } 

     .... 

    } 
+0

¿Por qué hacer 'como' en los puntales? – ChaosPandion

+0

Tienes razón, pensé que se veía apagado. Estaba siguiendo esta convención pero me doy cuenta de que es un caso diferente: [SettingsAllowAnonymous (false), CustomProviderData ("IPAddress; string")] cadena pública IPAddress {get {return base ["IPAddress"] como cadena; } set {base ["IPAddress"] = valor; }} –

Respuesta

28

En el primer ejemplo, en realidad no está heredando de dos clases, sino de una clase y una interfaz.

C# no permite la herencia múltiple de las clases, pero sí le permite implementar múltiples interfaces. Consulte this MSDN blog post para obtener más información sobre por qué.

Tendrá que hacer una interfaz IMembershipUser e implementarla en su clase User.

Las interfaces generalmente reciben nombres basados ​​en el nombre de la clase concreta con el prefijo I. Entonces la clase MembershipUser tendría una interfaz IMembershipUser. No hay nada que lo detenga con otro nombre, pero todos los que usan interfaces se utilizan para esta convención de nombres.

+0

Gracias Chris. ¿Podría echar un vistazo a mi edición cuando tenga un momento? De nuevo, gracias por tu ayuda. –

+1

@Code Sherpa - Realmente necesitaría ver más de tu código y tener más conversación de la que es posible a través de SO, pero si tienes propiedades duplicadas deberías buscar una jerarquía de clases diferente. – ChrisF

1

C# no es compatible con herencia múltiple.

En el primer ejemplo hereda de ProfileBase y declara que su clase implementa la interfaz ISessionMgrEntry.

Puede agregar tantas interfaces a una clase como desee (siempre que las implemente todas).

3

C# solo admite herencia simple. Puede encadenar juntas sus clases (es decir, MembershipUser hereda de ProfileBase) o usar interfaces.

5

en C# que sólo puede heredar de una clase, pero implementar tantas interfaces como desee. en su caso ProfileBase y MembershipUser son clases y ISessionMgrEntry es una interfaz.

2

C# solo permite la herencia simple: solo puede heredar de una clase base. En el primer caso, ISessionMgrEntry es una interfaz que es diferente de una clase base. He aquí un buen artículo sobre la diferencia: http://msdn.microsoft.com/en-us/library/ms973861.aspx

En el segundo caso se está tratando de heredar de ambos ProfileBase y MembershipUser, que no permitirá que el compilador. La mejor forma de evitar esto sería encapsular uno (o ambos) de ProfileBase y MembershipUser.

0

Las interfaces múltiples con nombres de miembros idénticos no son un problema. Si los miembros pueden compartir la misma implementación, simplemente cree un miembro público con el mismo nombre; si no pueden compartir la misma implementación, puede implementar explícitamente uno (o todos) los miembros.

Por ejemplo, IEnumerable<T> hereda IEnumerable, y ambos proporcionan un método GetEnumerator() con diferentes tipos de devolución. En consecuencia, IEnumerable.GetEnumerator() generalmente se implementan de forma explícita:

class Foo : IEnumerable<object>{ 
    // explicitly implement IEnumerable.GetEnumerator() 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public IEnumerator<object> GetEnumerator() 
    { 
     yield break; 
    } 
} 

Calling GetEnumerator() en IEnumerable.GetEnumerator() no es una llamada recursiva infinitamente; llama al miembro público del mismo nombre, no (es decir, el método IEnumerable.GetEnumerator()).

+0

gracias hombre - eso lo resolvió para mí. ¡muy apreciado! –

Cuestiones relacionadas