2009-12-26 7 views
1

J'ai une interface (appeler comme iMessage) qui a une méthode Check(), une classe implémente cette interfaceProblème avec les interfaces

interface IMessage 
{ 
    bool Check(); 
} 

class NewClass : IMessage 
{ 
    #region IMessage Members 

    public bool Check() 
    { 
     //Some logic 
    } 
} 

que tout va bien. Le problème est que je ne veux pas que cette méthode (Check()) soit publique, je veux la garder interne à l'asssembly, mais si je la rend interne alors le compilateur dit qu'elle n'implémente pas l'interface. Il doit être public pour implémenter l'interface. Que puis-je faire?

+0

Ma première question serait ... ce qui est le point? – bobbyalex

+0

Je ne veux pas qu'il soit accessible depuis l'extérieur de l'assemblage, donc je veux le garder comme interne non public. – viky

Répondre

8

Vous pouvez mettre en œuvre une méthode d'interface sans en faire partie de l'interface publique directe de la classe en utilisant Implémentation d'interface explicite syntaxe (supprimant le qualificatif d'accès et le préfixe du nom de l'interface à la méthode):

interface IMessage 
{ 
    bool Check(); 
} 

class NewClass : IMessage 
{ 
    bool IMessage.Check() { } 
} 

Cependant, toute personne pouvant effectuer un cast sur l'interface IMessage peut toujours appeler Check(). Ce n'est pas un moyen d'empêcher un appel à la méthode - seulement de désencombrer l'interface publique de la classe. Si l'interface est interne à votre assembly, seules les classes de cet assembly peuvent être converties en elle et appeler la méthode.

En général, .NET n'offre pas un moyen de faire uniquement certaines méthodes d'une interface interne à une implémentation de l'interface. C'est un domaine dans lequel vous pouvez envisager une classe de base abstraite - vous pouvez y créer des méthodes abstraites protégées que les héritiers peuvent implémenter sans les exposer à des appelants externes. Par exemple:

abstract class MessageBase 
{ 
    protected abstract bool Check(); 
} 

class NewClass : MessageBase 
{ 
    protected override bool Check() { ... } 
} 
+1

+1 pour la suggestion de classe de base abstraite, qui ressemble plus à ce qu'il cherche. –

+0

Mais l'interface est interne, donc les appelants en dehors de l'assemblée ne peuvent pas l'utiliser. – erikkallen

+0

@erikkallen: Oui - que je mentionne dans la dernière phrase du deuxième paragraphe de ma réponse. Si l'interface est interne à l'assembly, seul le code de cet assembly peut appeler la méthode. C'est là que les implémentations d'interface explicites peuvent vous aider à masquer les méthodes des appelants externes. – LBushkin

2

Les interfaces se rapportent à la façon dont les autres objets interagissent avec ce type d'objet, de manière publique. Si d'autres classes ne doivent pas accéder à la méthode Check(), cela ne doit pas faire partie de l'interface. Voici un MSDN discussion de ce sujet qui peut vous être utile.

+0

Je veux déclarer la méthode Check() comme interne non publique. – viky

+0

Cela dépend en fait de la visibilité de IMessage. En outre, les implémentations d'interface explicites sont là pour exactement ce scénario. Vous avez raison, cependant - la méthode reste accessible via IMessage. – peterchen

1
class NewClass : IMessage 
{ 
    #region IMessage Members 

    internal bool Check() 
    { 
     //Some logic 
    } 
    bool IMessage.Check() 
    { 
     return this.Check(); 
    } 
} 

Ceci fournit une implémentation interne, disponible uniquement aux classes au sein de cette assemblée, plus un explicit interface implementation qui vous permet de répondre aux exigences de l'interface. Pour le code d'un assembly externe pour appeler la méthode Check, il faudrait une référence IMessage à votre classe, pas une référence NewClass.

1

Sinon, vous pouvez utiliser une méthode abstraite sur une classe de base:

public abstract class Message 
{ 
    internal abstract bool Check(); 
} 

public class MyMessage : Message 
{ 
    internal override bool Check() 
    { 
     // do stuff 
    } 
} 
Questions connexes