membre interne dans une interface
J'ai une liste d'objets implémentant une interface, et une liste de l'interface:
public interface IAM
{
int ID { get; set; }
void Save();
}
public class concreteIAM : IAM
{
public int ID { get; set; }
internal void Save(){
//save the object
}
//other staff for this particular class
}
public class MyList : List<IAM>
{
public void Save()
{
foreach (IAM iam in this)
{
iam.Save();
}
}
//other staff for this particular class
}
Le code ne compile pas car le compilateur a besoin de tous les membres interface publique.
internal void Save(){
Mais je ne veux pas permettre à l'provenant de l'extérieur de ma DLL pour enregistrer le ConcreteIAM
, il ne doit être enregistré par le MyList
.
Toute façon de le faire?
Mise à jour#1: Salut à tous, merci pour les réponses, mais aucune n'est exactement ce dont j'ai besoin:
L'interface doit être publique, parce que c'est la signature du client à partir de l'extérieur de la dll à utiliser, avec ID
et d'autres propriétés que je n'ai pas pris la peine d'écrire dans l'exemple de garder les choses simples.
Andrew, je ne pense pas que la solution est de créer une usine pour créer un autre objet qui contiendra les IAM
membres + Enregistrer. Je suis encore à penser... d'autres idées?
- merci pour les réponses, mais aucune n'est exactement ce dont j'ai besoin: L'interface doit être publique, parce que c'est la signature du client à partir de l'extérieur de la dll à utiliser, avec ID et d'autres propriétés que je n'ai pas pris la peine d'écrire dans l'exemple de garder les choses simples. Andrew, je ne pense pas que la solution est de créer une usine pour créer un autre objet qui contiendra les IAM membres + Enregistrer. Je suis encore à penser... d'autres idées?
- Si vous voulez garder de la méthode d'enregistrement sur le concreteAM classe votre meilleur pari est probablement pour aller avec une classe de base abstraite, avec un intérieur abstrait méthode Save comme suggéré par Nathan W.
- mieux vaut tard que jamais, mais cela peut aider: stackoverflow.com/a/18944374/492
Vous devez vous connecter pour publier un commentaire.
Je pense que vous ne comprenez pas ce qu'est une interface pour. L'Interface est un contrat. Il précise que l'objet se comporte d'une certaine façon. Si un objet implémente une interface, cela signifie que vous pouvez compter sur elle qu'il a tout l'interface, les méthodes de mise en œuvre.
Maintenant, imaginez ce qui se passerait s'il y avait une interface comme vous demandez - public, mais avec un membre interne. Ce que cela signifierait? Un objet externe pourrait mettre en œuvre uniquement les méthodes publiques, mais pas l'intérieur. Lorsque vous recevez un tel objet externe, vous serez en mesure d'appeler seulement le public, mais pas à l'intérieur, parce que l'objet ne pouvait pas la mettre en œuvre. En d'autres termes - le contrat ne serait pas satisfaite. Pas tous les moyens seraient mis en œuvre.
Je pense que la solution dans ce cas est de diviser votre interface en deux. Une interface sera publique, et c'est ce que vos objets externes mettrait en œuvre. L'autre interface est interne et contiendra votre
Save()
internes et d'autres méthodes. Peut-être cette deuxième interface pourrait même hériter de la première. Vos propres objets internes serait alors de mettre en œuvre les deux interfaces. De cette façon, vous pourriez même faire la distinction entre les objets externes (ceux qui n'ont pas l'interface interne) et les objets internes.Faire une autre interface qui est interne, et utiliser explicitement la mise en œuvre de la méthode.
InternalIAM
comme un type de paramètre.Je ne pense pas que vous devriez être à l'aide d'une interface ici, peut-être devriez-vous utiliser un résumé de la base de quelque chose comme.:
Vont encore vous permettent de faire cela:
Je pense que la meilleure chose à faire serait de séparer l'intérieur et des membres du public en deux interfaces. Si vous héritent de l'interface vous pouvez toujours déclarer les membres publiquement, mais la visibilité des membres internes seront dictées par la visibilité de l'interface elle-même.
C'est exactement ce que je parle dans mon article Des amis et interface interne des membres à aucun coût avec le codage des interfaces.
L'essence de l'article
À partir de maintenant on ne votre assemblée peut appeler la
Save()
méthode, depuis une instance de laInternal
classe ne peut être créé par votre assemblée.Si vous ne voulez pas que les appelants externes pour être en mesure d'appeler votre méthode Save (), pourquoi ne pas rendre l'ensemble concreteIAM classe interne?
Ou, si vous voulez la classe public, mais pas l'interface, faire de l'ensemble de l'interface interne. Je pense que l'interface interne peut être ajouté à un public de classe (mais je n'ai pas essayé...)
Peut-être que vous voulez séparer l'enregistrement de vos articles en un autre ensemble de classes qui sont internes à votre assemblée:
Interface les membres sont censés être publics.. quoi que ce soit d'autre, et vous devriez penser si vous besoin de quelque chose d'autre. Dans ce cas, vous
Maintenant la conception des pensées de côté, vous pouvez le faire via l'Interface Explicite de mise en Œuvre.
IPersist est interne, ne sont pas disponibles à l'extérieur de l'assemblage parent et depuis il est explicitement mis en œuvre, il ne peut pas être appelé sans IPersist de référence.
Mise à jour De votre dernière réponse, nous avons plus de contraintes.
L'Interface doit être public, il doit contenir la méthode Save, qui ne devrait pas être accessible au public.
Je dirais de retourner à la planche à dessin... quelque chose ne semble pas juste. À mon humble avis, Vous ne pouvez pas faire cela avec une interface unique. Comment diviser en 2 interfaces, le public et l'interne?
Pourquoi n'utilisez-vous pas les classes internes de contrôle de l'accessibilité de vos méthodes?
Exemple:
Votre assemblée primaire
Secondaire de l'assemblée
De ce modèle permet de mettre en œuvre
Save()
méthode dans d'autres assemblées, mais seulementItemCollection
qui est intérieur de la classe deItem
pouvez l'appeler. Brillant, n'est-ce pas?Aller avec deux interfaces:
La mise en œuvre de la Save() doit être explicite pour empêcher les clients de l'appeler.
J'ai eu la même situation et pensé que cela pourrait aider. (pas sûr si cela n'est pas nécessaire à ce moment ou pas)
C'est une pièce de théâtre cas pour moi: dans le cas où supposons qu'il y est une interface qui a une API qui est interne à la DLL et certaines API peut être accessible depuis l'extérieur de la DLL. Depuis l'interface est une classe abstraite, au lieu de le définir comme une interface, vous pouvez définir une classe abstraite.
Je me demandais sur la même question ici,
et je suis tombé sur cette question...
Que je pensais sur ce, j'ai compris je n'ai pas besoin interne méthode dans l'Interface en premier lieu.
Je peux y accéder par le biais de ma Classe de Béton,
et de laisser le Contrat pour le code Côté.
Dans votre exemple: