2010-02-17 7 views
3

Je programme en C# .NET. Il est possible d'abandonner la procédure set d'une propriété de classe sans lancer une exception?Pouvez-vous abandonner une procédure d'ensemble d'une propriété

Voici ce que je veux faire ...

public int RandomProperty 
{ 
    set 
    { 
    DialogResult answer = new DialogResult(); 
    answer = MessageBox.Show("This process could take up to 5 min. Are you sure you want to continue?"); 
    if(answer = DialogResult.No) 
     CancelSet // Can I do something similar here? 
    else 
    { 
     ...Do set procedure 
    } 
    } 
} 

Je ne pense pas que je peux utiliser une méthode (au lieu d'une propriété) parce que je suis en train de cette valeur avec un PropertyGrid.

+1

Vous pourriez envisager d'en faire une méthode plutôt qu'une propriété, par exemple SetRandomProperty (int). Les setters sont généralement censés être très rapides. – JeffH

+1

Vous pouvez juste 'return;' quand vous voulez, mais vraiment, une fonction set ne devrait pas être longue, ne devrait pas nécessiter d'entrée utilisateur (elle a déjà la valeur après tout), et ne devrait pas lancer d'exceptions. Vous devriez vraiment avoir cette logique dans une fonction séparée, et non dans une méthode set. –

+0

@Tout le monde. Je réalise que c'est une mauvaise idée d'avoir le code UI dans une propriété de classe mais j'utilise une grille de propriété pour définir cette propriété et il n'y a vraiment aucun moyen d'insérer une question MessageBox entre l'interface propertygrid et la classe à laquelle elle est liée , droite? – PICyourBrain

Répondre

8

Vous ne devez en aucun cas faire cela. Une propriété doit toujours être rapide et représente logiquement une propriété de quelque chose. Idéalement, cela ne devrait jamais échouer. Il ne devrait certainement pas produire d'effets secondaires tels que l'apparition de l'interface utilisateur. Vous violez toutes ces directives importantes. Ne fais pas ça.

En outre, votre conception de l'interface utilisateur est mauvaise. Ne demandez pas à un utilisateur à l'avance "cela pourrait prendre un certain temps, êtes-vous sûr?" puis les punir avec une longue attente s'ils cliquent sur oui. Au lieu de cela, démarrez l'opération, et si elle ne revient pas rapidement, faites apparaître un élément de l'interface utilisateur qui affiche une barre de progression et une estimation du temps restant avec un bouton d'annulation.

Vous devriez probablement écrire votre opération de longue durée comme une méthode asynchrone qui peut être annulée proprement sur un autre thread. Une bonne architecture pour ce genre de choses est que votre méthode retourne immédiatement un objet qui expose des événements comme "Je suis toujours en cours d'exécution et voici jusqu'où je suis", ou "J'ai fini maintenant et voici la résultat ", ou" J'ai eu une erreur en essayant de faire l'opération et voici ce que c'est ". Cet objet peut également exposer une méthode "cancel" qui sait comment communiquer avec le thread de travail et l'arrêter proprement. L'appelant de la méthode qui obtient cet objet peut alors décider comment afficher l'interface utilisateur pour l'utilisateur.

Avec cette architecture, vous séparez clairement votre logique d'interface utilisateur, votre logique d'asynchronisme et votre logique de processus métier. C'est un travail, mais ça rapporte plus tard.

1

Il suffit de sortir de l'appareil. Vous devrez utiliser un champ privé pour contenir la valeur de ce que vous voulez définir, mais revenir dans le "annuler" devrait le faire.

12

OMI ce n'est tout simplement pas une bonne chose à faire - l'attente est que si le set ne lui assigne pas la valeur. Tester dans l'interface utilisateur (ou n'importe où) avant en faisant set, ou lancer et gérer une exception. Sinon, l'appelant pourrait être moins confus par une méthode:

public bool TrySetRandomProperty(SomeType value) { 
    ... 
} 

qui retourne true ou false pour indiquer s'il est arrivé. Vous devriez également éviter de faire saigner le code de l'interface utilisateur dans la logique du domaine; peut-être utiliser un événement pour laisser l'interface utilisateur parler à l'utilisateur sans infliger une implémentation de l'interface utilisateur particulière sur l'appelant?

3

Ugh. Voulez-vous vraiment impliquer l'interface utilisateur dans une propriété de classe? Ne devriez-vous pas faire cette vérification plus loin dans l'interface utilisateur?

2

Vous pouvez certainement le coder de cette façon, mais ne définissez pas le champ. Cependant, vous avez un très mauvais design lorsque vous mélangez l'interface utilisateur dans votre code de bas niveau. Poser la question avant de définir la propriété est une option unique.

Questions connexes