7
votes

Mise en œuvre d'une classe à partir de 2 interfaces partageant certaines parties

est ce qui suit n'est pas une bonne pratique?

public interface IMyImmutableData
{
    int Data { get;}
}

public interface IMyMutableData
{
    int Data { set;get;}//implements both get and set
}

public class MyData : IMyImmutableData, IMyMutableData
{
    public int Data{get;set;} //implements both IMyImmutableData, IMyMutableData
}

void Main()
{
    MyData myData = new MyData{Data=10};
    Console.WriteLine(myData.Data);
}


1 commentaires

Tout comme une note, je pense que imyreadonlydata porterait une meilleure signification que imyimmutabertadata , puisque l'objet est mutable du tout.


5 Réponses :


3
votes

Vous devez faire une ou deux des implémentations explicite: xxx

Lorsque vous marquez l'une comme explicite, elle ne peut être accédée que lorsqu'elle est spécifiquement mise à ce type: < PRE> XXX

Si vous choisissez de ne pas marquer l'une comme explicite, ce sera la propriété choisie lorsqu'elle est en forme de type approprié.


1 commentaires

Juste une note - les implémentations explicites ne peuvent pas être marquées publiques, bien qu'elles puissent être consultées publiquement via l'interface, selon la réponse de Jon Skeet ici: stackoverflow.com/questions/1392252/ ...



1
votes

Je pense que dans ce cas, votre structure va bien. Vous ne souhaitez pas mettre en œuvre explicitement les interfaces via des propriétés distinctes, car alors les données que vous accédez via l'interface immuable sera effectivement différente que celle de l'interface mutable. < P> En outre, votre code actuel est probablement plus complexe, car dans ce cas, il n'y a pas d'ambiguïté: vous accédez à des données via l'objet lui-même, les interfaces ne doivent donc pas être prises en compte.

Une solution avec une implémentation d'interface explicite serait d'utiliser un champ de support commun, plutôt que des propriétés automatiques: xxx


1 commentaires

J'ai marqué cette réponse comme "la" réponse parce que c'était une armoire à ma réponse. Mais je pense que je vais utiliser la solution de Joel B Fan, comme il est plus élégant.



5
votes

Je pense que vous pouvez ignorer l'avertissement de Restomer, car l'ambiguïté est intentionnelle.

Cependant, une classe d'emballage est généralement utilisée pour fournir un accès réadéniste à quelque chose, de cette façon que cela ne peut pas être lancé à rien qui fournit plus de fonctionnalités. . P>

public class MyReadonlyData : IMyReadonlyData {
    private MyData instance;

    public int Data {
        get {
            return instance.Data;
        }
    }

    public MyReadonlyData( MyData mydata ) {
        instance = mydata;
    }
}
// no access to original object or setters, period.


1 commentaires

Bien que j'ai accepté la réponse de Dlev, j'aime votre solution et je voudrais retravailler mon projet pour utiliser votre idée. C'est plus élégant (imo).



0
votes

Vous pouvez lancer la variable et dire au compilateur ce que vous voulez dire exactement: (résoudre l'ambiguïté) xxx


0 commentaires

0
votes

Vous avez besoin d'une interface combinée avec un "nouveau" qualificatif sur l'interface lecture-écriture pour éviter la squawk. En outre, vos interfaces sont mal nommées. De meilleurs noms seraient quelque chose comme "Ireadabledata" et "iwridabledata", et "IreadwredraData". Notez que, tandis que "IReadableData" ne fournit aucun moyen de mutager les données, qu'aucune étreinte de l'imagination implique que les données sont immuables. Si quelque chose est immuable, cela ne sera changé par personne. Ce ne serait clairement pas le cas avec un objet de type myData.


0 commentaires