2009-07-03 20 views
16

Je reçois une erreur de compilation de la propriété suivante.
L'erreur est:Modificateurs d'accès sur les membres de l'interface en C#

"Le modificateur 'public' n'est pas valide pour ce produit"

public System.Collections.Specialized.StringDictionary IWorkItemControl.Properties 
{ 
    get { return properties; } 
    set { properties = value; } 
} 

mais si je retire le IWorkItemControl il compile bien. Pourquoi ai-je cette erreur et quelle est la différence entre avoir/ne pas avoir le nom de l'interface dans la signature?

Répondre

41

Explicit interface implementation ne vous permet pas de spécifier des modificateurs d'accès. Lorsque vous implémentez un membre d'interface explicitement (en spécifiant le nom de l'interface avant le nom de membre), vous pouvez accéder à ce membre uniquement en utilisant cette interface. En gros, si vous le faites:

System.Collections.Specialized.StringDictionary IWorkItemControl.Properties 
{ 
    get { return properties; } 
    set { properties = value; } 
} 

Vous ne pouvez pas faire:

MyClass x = new MyClass(); 
var test = x.Properties; // fails to compile 
// You should do: 
var test = ((IWorkItemControl)x).Properties; // accessible through the interface 

Il existe plusieurs cas d'utilisation pour EII. Par exemple, vous souhaitez fournir une méthode Close à votre classe pour libérer des ressources acquises, mais vous souhaitez toujours implémenter IDisposable. Vous pourriez faire:

class Test : IDisposable { 
    public void Close() { 
     // Frees up resources 
    } 
    void IDisposable.Dispose() { 
     Close(); 
    } 
} 

De cette façon, les consommateurs de la classe ne peuvent appeler directement Close (et ils ne seront même pas voir Dispose dans la liste IntelliSense) mais vous pouvez toujours utiliser la classe Test où un IDisposable devrait (par exemple dans une instruction using).

Un autre cas d'utilisation pour EII fournit différentes implémentations d'un membre d'interface portant le même nom pour deux interfaces:

interface IOne { 
    bool Property { get; } 
} 

interface ITwo { 
    string Property { get; } 
} 

class Test : IOne, ITwo { 
    bool IOne.Property { ... } 
    string ITwo.Property { ... } 
} 

Comme vous le voyez, sans EII il est même pas possible à mettre en œuvre les deux interfaces de cet exemple une classe unique (car les propriétés diffèrent simplement en type de retour). Dans d'autres cas, vous pouvez intentionnellement fournir un comportement différent pour les vues individuelles d'une classe via différentes interfaces.

0

Tous les éléments d'une interface doivent être publics. Après tout, une interface est la vue publique d'un objet.

Depuis Propriétés est un élément d'une interface IWorkItemControl, il est déjà public et vous ne pouvez pas spécifier le niveau d'accès, même à préciser qu'il est redondante public.

+1

Ce n'est pas une raison très forte car vous devez toujours spécifier manuellement public pour tous les membres implémentés implicitement. Si tel était le cas, le compilateur pourrait automatiquement supposer ceux-ci aussi publics. –

+0

Ceci est faux, car vous pouvez avoir des interfaces internes. –