J'ai quelques questions relatives à la conception de ma classe User
, mais elles sont suffisamment différentes pour que je pense qu'elles devraient être indépendantes Questions.
Ainsi, le premier est lié à l'héritage des classes de base. Je suis actuellement hérité de deux classes, ProfileBase
et ISessionMgrEntry
en tant que telles:
public class User : ProfileBase, ISessionMgrEntry
Mais je veux aussi hériter d'une troisième classe, MembershipUser
, comme ceci:
public class User : ProfileBase, MembershipUser, ISessionMgrEntry
Cependant, le compilateur ne me laissera pas faire cela. Pourquoi? Et comment puis-je obtenir Autour de cela?
Merci.
PS - ASP.NET 3.5/C #
MODIFIER
Salut. Je pense que la solution ci-dessous peut fonctionner pour ce que je cherche à atteindre. Cela semble assez simple et direct. Je le fais afin de pouvoir créer un objet User
complet/combiné. Quelqu'un voit-il une raison pour laquelle cela pourrait causer des problèmes? Celui qui est apparu alors que j'étais Ding est un chevauchement de propriétés. Par exemple, MembershipUser
et ProfileBase
partagent "UserName
". Devrais-je choisir l'un ou l'autre ou s'agit-il d'un défaut de conception? Suggestions? Merci encore.
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; }
}
....
}
Dans le premier exemple, vous n'héritez pas de deux classes, mais d'une classe et d'une interface.
C # n'autorise pas l'héritage multiple de classes, mais vous permet d'implémenter plusieurs interfaces. Voir cet article de blog MSDN pour plus d'informations sur les raisons.
Vous devrez créer une interface IMembershipUser
et l'implémenter dans votre classe User
.
Des noms sont généralement donnés aux interfaces en fonction du nom de classe concret préfixé par un I
. La classe MembershipUser
aurait donc une interface IMembershipUser
. Rien ne vous empêche d'utiliser un autre nom, mais tous ceux qui utilisent des interfaces sont habitués à cette convention d'appellation.
en c #, vous pouvez simplement hériter d'une classe , mais implémenter autant d'interfaces que vous voulez . dans votre cas ProfileBase
et MembershipUser
sont des classes et ISessionMgrEntry
est une interface.
C # ne prend en charge que l'héritage simple. Vous pouvez soit chaîner vos classes (c'est-à-dire que MembershipUser
hérite de ProfileBase
) ou utiliser interfaces
.
C # n'autorise pas l'héritage multiple .
C # n'autorise qu'un seul héritage: vous ne pouvez hériter que d'une seule classe de base. Dans le premier cas, ISessionMgrEntry
est une interface différente de la classe de base. Voici un bon article sur la différence: http://msdn.Microsoft.com/en-us/library/ms973861.aspx
Dans le second cas, vous essayez d'hériter de ProfileBase
et MembershipUser
, ce que le compilateur n'autorisera pas. La meilleure façon de contourner ce problème serait d’encapsuler l’une (ou les deux) de ProfileBase
et MembershipUser
.
C # ne prend pas en charge l'héritage multiple.
Dans le premier exemple, vous héritez de ProfileBase
et déclarez que votre classe implémente l'interface ISessionMgrEntry
.
Vous pouvez ajouter autant d'interfaces que vous le souhaitez dans une classe (à condition de toutes les implémenter).
Plusieurs interfaces avec des noms de membres identiques ne posent pas de problème. Si les membres peuvent partager la même implémentation, créez simplement un membre public portant le même nom. s'ils ne peuvent pas partager la même implémentation, vous pouvez simplement implémenter explicitement un (ou tous) des membres.
Par exemple, IEnumerable<T>
hérite de IEnumerable
et les deux fournissent une méthode GetEnumerator()
avec des types de retour différents. Par conséquent, IEnumerable.GetEnumerator()
est généralement implémenté explicitement:
class Foo : IEnumerable<object>{
// explicitly implement IEnumerable.GetEnumerator()
IEnumerator IEnumerable.GetEnumerator ()
{
return GetEnumerator();
}
public IEnumerator<object> GetEnumerator ()
{
yield break;
}
}
L'appel de GetEnumerator()
dans IEnumerable.GetEnumerator()
n'est pas un appel infiniment récursif; il appelle le membre public du même nom, pas lui-même (c'est-à-dire la méthode IEnumerable.GetEnumerator()
).