8
votes

C #: Propriétés avec différents types de retour sur des classes dérivées

J'ai essayé de rechercher une réponse à ce problème mais je n'ai pas pu trouver beaucoup, probablement parce que je ne sais pas comment le chercher correctement, alors cela va ici. Toute aide est très appréciée.

avec la classe de base qui ressemble à xxx

et de classes dérivées qui ressemblent à xxx

Pendant l'exécution, la fonction reçoit une collection d'objets "propriété". Que dois-je faire pour pouvoir obtenir la "valeur" de chacun? Dois-je avoir un gros si instruction pour interroger le type d'objet "propriété"? Sinon, y a-t-il une solution plus élégante?

J'ai essayé de définir une propriété abstraite "valeur" à remplacer mais que les types de retour sont différents, cela n'a pas fonctionné. J'ai aussi essayé de jouer avec l'observation de la propriété "valeur", mais je ne pouvais pas le faire fonctionner. L'idée d'utiliser une variante de type COM ne sonne pas très appropriée, non plus.

Merci beaucoup à l'avance.

EDIT:

J'aurais dû ajouter Détails sur ce que j'essaie de faire. Les propriétés sont affichées dans une application WinForms. Différentes "Textbox" es représentent différentes propriétés et sont filtrées pour une entrée correcte (selon le type). Les valeurs actualisées sont relues et stockées. L'objet conteneur sera sérialisé dans JSON et désérialisé sur un client Android et iPhone et, éventuellement, ces valeurs seront transmises à un calque exécutant le code natif C ++ faisant des trucs opengl. Je ne sais pas à l'avance le type de toutes les propriétés nécessaires pour que le Middleman, je voulais rendre mon code aussi robuste que possible tout en pouvant alimenter le moteur OpenGL.


3 commentaires

Mais c'est une variante bien sûr. Vous pouvez peindre un visage plus heureux C # - en l'offrant dynamique .


Qu'est-ce que vous avez l'intention de faire avec la valeur?


Ajouté plus de détails au texte de la question.


4 Réponses :


14
votes

Vous pouvez utiliser une classe générique:

public static Property<T> AsProp<T>(this T value, string name)
{
    return new Property<T>(name,value);
}

var intProp = 32.AsProp("age");
var strProp = "Earl".AsProp("name");
var enumProp = ColorEnum.Magenta.AsProp("eye color");


3 commentaires

La méthode makeproperty doit-elle être statique?


@Otiel: Non, pas pour une raison particulière. (Honnêtement, cela dépend de l'endroit où vous voulez le définir / l'utiliser). Cela peut être statique cependant, donc je modifierai le code pour réfléchir cela.


+1. Merci beaucoup d'avoir pris le temps de fournir une réponse élégante. Mon cas était davantage sur l'interaction de l'interface utilisateur et la structure des propriétés et la réponse de MiniTech m'a donné la direction à parcourir. En suivant les étapes suivantes, je vais inspecter votre réponse plus en détail et incorporerez les idées au fur et à mesure de leur intégration dans notre cas.



4
votes

Vous devriez simplement utiliser le type objet . Qu'est-ce que vous essayez d'accomplir? Le problème ici n'est pas la structure de vos classes, c'est la fonction qui reçoit la collecte des objets . Il est impossible de jeter quelque chose à un type inconnu, car vous ne savez pas quel type de variable doit être stocké.

Si fondamentalement, votre propriété Property.Value doit être de type objet . Dans votre méthode qui utilise les objets , vous devez faire quelque chose avec eux et ce que vous décidez décidera de la structure de la structure. Imprimez-vous des valeurs? Avoir une valeur * de la valeur hériter d'un abstrait PropertyValue Classe et remplacement Tostring () Pour renvoyer une catégorie appropriée.



3
votes

J'ai fait quelques modifications à votre code d'échantillon et j'ai obtenu ce résultat ...

   abstract public class Property
    {
        private readonly String _name;
        public Property(String propertyName)
        {
            _name = propertyName;
        }
        public String Name
        {
            get { return _name; }
        }
        abstract public override String ToString();
    }
    public class StringProperty : Property
    {
        private readonly dynamic _value; // different properties for different types 
        public StringProperty(String propertyName, dynamic value)
            : base(propertyName)
        {
            this._value = value;
        }
        public dynamic Value // different signature for different properties 
        {
            get { return _value; }
        }
        public override String ToString()
        {
            return base.Name + ": " + _value;
        }
    }
    static void Main(string[] args)
    {
        StringProperty sp = new StringProperty("A double", 3.444);
        StringProperty sp2 = new StringProperty("My int", 4343);
        StringProperty sp3 = new StringProperty("My directory", new  DirectoryInfo("Some directory"));
        StringProperty sp4 = new StringProperty("My null", null);
        Console.WriteLine(sp);
        Console.WriteLine(sp2);
        Console.WriteLine(sp3);
        Console.WriteLine(sp4);
    }
}


2 commentaires

Pourquoi "dynamique" est-il meilleur que "objet" dans ce cas?


À zmbq. Ce n'est peut-être pas, je ne sais pas assez sur le cas. Toutefois, à un moment donné à l'aide de l'objet, vous utiliserez des mises à jour explicites. Les résultats pourraient donc être tout à fait si (int) «10» par exemple. Cela signifie que vous finissez par faire de plus en plus d'échafaudages pour faire face à ne pas savoir quel type de votre propriété devrait être et vous devez ajouter plus d'échafaudages pour chaque nouveau type. Dynamic résout cela, mais vous donne d'autres problèmes. C'est un choix de conception, je dois le regarder et voir où est le plus pratique de compromettre.