52 votes

Beaucoup de première chance Microsoft.CSharp.RuntimeBinderExceptions levées lorsqu'il s'agit de dynamique

J'ai une "norme" dictionnaire dynamique de type classe en C# -

class Bucket : DynamicObject
{
    readonly Dictionary<string, object> m_dict = new Dictionary<string, object>();

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        m_dict[binder.Name] = value;
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return m_dict.TryGetValue(binder.Name, out result);
    }
}

Maintenant je l'appelle, comme suit:

static void Main(string[] args)
{
    dynamic d = new Bucket();
    d.Name = "Orion"; // 2 RuntimeBinderExceptions
    Console.WriteLine(d.Name); // 2 RuntimeBinderExceptions
}

L'application fait ce que vous attendez, mais la sortie de débogage ressemble à ceci:

Une exception de première chance de type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' s'est produite dans Microsoft.CSharp.dll
Une exception de première chance de type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' s'est produite dans Microsoft.CSharp.dll
'ScratchConsoleApplication.vshost.exe' (Géré (v4.0.30319)): Chargé 'De Manière Anonyme Hébergé DynamicMethods Assemblée"
Une exception de première chance de type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' s'est produite dans Microsoft.CSharp.dll
Une exception de première chance de type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' s'est produite dans Microsoft.CSharp.dll

Toute tentative d'accès à un membre dynamique semble sortie d'un RuntimeBinderException pour les journaux de débogage. Même si j'ai conscience que la première chance exceptions ne sont pas un problème en soi, cela ne cause de certains problèmes pour moi:

  1. J'ai souvent le débogueur réglé sur "arrêt sur les exceptions, comme je suis en train d'écrire des applications WPF, et sinon toutes les exceptions fin de compte converti en DispatcherUnhandledException, et toutes les informations que vous voulez, c'est perdu. WPF suce comme ça.

  2. Dès que j'ai touché tout le code qui utilise l' dynamic, la sortie de débogage journal est assez inutile. Tous les utiles tracer des lignes que je me soucie d'obtenir cachés parmi tous les inutiles RuntimeBinderExceptions

Est il possible que je peux désactiver cette fonction, ou est l' RuntimeBinder , malheureusement, juste construit comme ça?

Merci, Orion

26voto

Igor Zevaka Points 32586

Chaque fois qu'une propriété sur un objet dynamique est résolu, le moteur d'exécution tente de trouver une propriété qui est défini au moment de la compilation. De DynamicObject doco:

Vous pouvez également ajouter vos propres membres de les classes dérivées de la DynamicObject classe. Si votre classe définit propriétés et remplace également le TrySetMember méthode, la dynamique language runtime (DLR) utilise d'abord la langue liant à regarder pour une charge statique définition d'une propriété dans la classe. Si il n'y a pas de telle propriété, le DLR appelle la TrySetMember méthode.

RuntimeBinderException est renvoyée chaque fois que l'exécution ne peut pas trouver un définis de manière statique de la propriété(c'est à dire ce qui serait une erreur de compilateur en 100% statiquement typé monde). De l'article MSDN

...RuntimeBinderException représente un défaut de liaison dans le sens d'une d'habitude erreur du compilateur...

Il est intéressant de noter que si vous utilisez ExpandoObject, vous obtenez seulement une exception lors de l'utilisation de la propriété:

dynamic bucket = new ExpandoObject();
bucket.SomeValue = 45;
int value = bucket.SomeValue; //<-- Exception here

Peut - ExpandoObject pourrait être une alternative? Si il n'est pas convenable que vous aurez besoin de regarder dans la mise en œuvre de IDynamicMetaObjectProvider, qui est de savoir comment ExpandoObject n'dynamique de l'expédition. Cependant, il n'est pas très bien documenté et MSDN vous renvoie à la DLR CodePlex pour plus d'info.

23voto

Anthony Johnston Points 3133

C'était de me tracasser, trop. J'ai ajouté de l'exception à la liste des exceptions pour que je puisse le désélectionner. Il suffit de suivre ces étapes:

  • Dans le menu Débogage, sélectionnez les Exceptions.
  • Cliquez sur le bouton "Ajouter..." en bas à droite.
  • Choisissez "Common Language Runtime Exceptions" à partir de la liste déroulante Type.
  • Type "De Microsoft.CSharp.RuntimeBinder.RuntimeBinderException" que le nom.
  • Cliquez sur OK.
  • Le type d'exception apparaît maintenant sur la liste. Juste le désélectionner.

Je souhaite que ce paramètre pourrait être enregistrées à travers des solutions, mais je ne pense pas qu'il le peut, donc vous devrez réappliquer ce paramètre pour chaque solution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X