Pourquoi ne WPF en charge la liaison de propriétés d'un objet, mais pas sur des champs?
J'ai un service WCF qui passe autour de mises à jour de statut via une structure comme ceci:
[DataContract]
public struct StatusInfo
{
[DataMember] public int Total;
[DataMember] public string Authority;
}
...
public StatusInfo GetStatus() { ... }
J'expose une propriété dans un ViewModel comme ceci:
public class ServiceViewModel : ViewModel
{
public StatusInfo CurrentStatus
{
get{ return _currentStatus; }
set
{
_currentStatus = value;
OnPropertyChanged( () => CurrentStatus );
}
}
}
Et XAML comme suit:
<TextBox Text="{Binding CurrentStatus.Total}" />
Quand je lance l'application, je vois des erreurs dans la fenêtre de sortie indiquant que le Total de la propriété ne peut pas être trouvé. J'ai vérifié et revérifié et j'ai tapé correctement. La il m'est apparu que les erreurs indiquent spécifiquement que la "propriété" ne peut pas être trouvé. L'ajout d'une propriété à la struct fait le travail très bien. Mais cela me semble étrange que WPF ne peut pas gérer une voie de liaison vers les champs. Du point de vue syntaxique leur accès est le même dans le code et il semble ridicule d'avoir à créer une vue personnalisée modèle juste pour la StatusInfo struct. Ai-je manqué quelque chose à propos de WPF liaison? Pouvez-vous lier à un champ ou est la propriété de liaison de la seule manière possible?
OriginalL'auteur Paul Alexander | 2009-05-09
Vous devez vous connecter pour publier un commentaire.
Liaison généralement ne pas travailler aux champs. La plupart de liaison est basée, en partie, sur la ComponentModel
PropertyDescriptor
modèle, qui (par défaut) travaille sur propriétés. Cela permet de notifications, validation, etc (rien de ce qui fonctionne avec des champs).Pour plus de raisons que je ne peux aller dans, les domaines publics sont une mauvaise idée. Ils devraient être des propriétés, en fait. De même, les structures mutables sont un très mauvaise idée. Pas moins, il protège contre les pertes de données imprévues (communément associée avec les structures mutables). Ce doit être une classe:
Il va maintenant se comporter comme vous pensez qu'il devrait. Si vous voulez qu'il soit un immuable struct, ce serait OK (mais de liaison de données serait une façon seulement, bien sûr):
Cependant, je tiens tout d'abord à la question pourquoi c'est un struct dans la première place. Il est très rare à écrire un struct dans .NET languages. Gardez à l'esprit que la WCF "mex" proxy couche de créer une classe à la consommation de toute façon (sauf si vous utilisez de l'assemblée de partage).
En réponse au "pourquoi utiliser les structures" réponse"inconnu (google)"):
Si c'est une réponse à ma question, c'est à tort à de nombreux égards. Tout d'abord, les types de valeur comme variables sont communément attribués (première) sur la pile. Si ils sont poussés dans le tas (par exemple dans un tableau/liste) il n'y a pas beaucoup de différence dans les frais généraux à partir d'une classe - un petit peu de l'objet-tête plus une référence. Les structures doivent toujours être petit. Quelque chose avec de multiples champs de la sur-dimensionné, et la volonté de meurtre de la pile ou de la juste cause de la lenteur en raison de la blitting. En outre, les structures doivent être immuables - unlesss vous vraiment savez ce que vous faites.
Peu près tout ce qui représente un objet doit être immuatable.
Si vous frappez une base de données, la vitesse de la struct vs classe est un non-problème par rapport à une sortie de processus et probablement sur le réseau. Même si il est un peu plus lent, cela ne signifie rien par rapport au point de trouver le juste - à-d. le traitement des objets en tant qu'objets.
Que certaines métriques sur 1M objets:
basé sur les éléments suivants (la différence de vitesse est dans l'allocation des objets, pas de terrain vs propriété). Donc environ 5x plus lent, mais toujours très, très rapide. Car cela ne va pas être le goulot d'étranglement, ne pas prématurément optimiser cette!
soupir, ici, nous allons à nouveau, "C++ est plus rapide que tout, jamais, et doit être utilisé en tout temps" (soupir). Dans une grande variété d'applications, il n'y a pas de différence sensible, autre que celle d'être beaucoup plus facile pour obtenir le droit.
Je n'ai jamais dit C++ a été plus rapide! La conclusion de tels indiqué que vous avez un peu de sérieux les idées préconçues (ou peut-être des idées fausses). "Dans une grande variété d'applications, il n'y a pas de différence sensible, autre que celle d'être beaucoup plus facile pour obtenir le droit" - donc, nous sommes d'accord, bien que le C++ peut être plus rapide, ce n'est pas important - cependant, C++ rend plus facile pour y arriver et cela est important. Ou j'ai peut-être mal interprété ce que vous avez dit pour appuyer mon argument... Soupir en effet.
peut-être que j'ai mal compris le sens de "en tant que programmeur c++ ... mais toujours très, très lente"
Votre test de performance est probablement trop courte pour mesurer correctement la GC frais généraux. Essayez cette modification de vos tests: pastebin.com/Ajkj0hdm - maintenant, les classes sont 12x plus lent, parce que 80% du temps est passé dans le GC. Maintenant manivelle de la TAILLE jusqu'à 10M et regarder les "octets privés": 200 MO pour les structures, l'escalade de 1 GO pour les classes.
OriginalL'auteur Marc Gravell
Je ne peux que deviner pourquoi ils prennent uniquement en charge les propriétés: peut-être parce qu'elle semble être une convention universelle dans le .NET framework ne jamais exposer les champs mutables (sans doute pour préserver la compatibilité binaire), et ils en quelque sorte prévu tous les programmeurs de suivre la même convention.
Aussi, bien que les champs et les propriétés sont accessibles avec la même syntaxe, la liaison de données utilise la réflexion, et (ce que j'ai entendu) réflexion doit être utilisé différemment pour accéder aux champs de l'accès à des propriétés.
OriginalL'auteur Qwertie