44 votes

Erreur en C #: "un arbre d'expression ne peut pas contenir d'accès de base" - pourquoi pas?

J'ai été l'appel d'une méthode qui accepte Expression<Func<bool>>.

Dans le cadre de l'expression, j'ai été en passant:

this.Bottom == base.lineView.Top

Le compilateur m'a donné une erreur

une arborescence d'expression ne peut pas contenir d'accès à la base

Alors j'ai tout simplement changé d'

this.Bottom == this.lineView.Top

parce que le membre a été protégé de toute façon, et maintenant ça fonctionne.

Mais cette erreur m'a vraiment: pourquoi diable serait-ce base être un problème? Surtout si vous utilisez this au lieu de cela va fonctionner, mais du point de vue syntaxique être le même résultat (même variable est accessible)?

43voto

Jon Skeet Points 692016

En regardant l' System.Linq.Expressions.Expression de la documentation, je ne pense pas qu'il y a un type d'expression qui est la base de l'accès des membres". N'oubliez pas que même si dans votre cas, il signifie la même chose que juste this, dans d'autres cas, il ne serait pas:

class Test
{
    void Foo()
    {
        Expression<Func<string>> baseString = () => base.ToString();
    }

    public override string ToString()
    {
        return "overridden value";
    }
}

Ici qui pourrait représenter un non-virtuel appel à l' Object.ToString() ( this). Je ne vois pas comment cela pourrait être représenté dans une arborescence d'expression, d'où l'erreur.

Maintenant, cela nous amène à nous poser la question de pourquoi il n'y a pas une représentation de non-virtuel membre de base de l'invocation dans l'expression des arbres - je crains que je ne peux pas répondre à cette partie... bien que je ne peux voir que si vous avez pu construire que l'expression de la programmation, qui vous permettra de contourner normal polymorphisme de l'extérieur plutôt que seulement à partir de l'intérieur de la classe elle-même (ce qui est le cas normal). C'est peut être la raison. (Certes, il existe d'autres moyens de l'appel de méthodes non-pratiquement, mais c'est une autre affaire, et j'ose dire qu'il y a des situations où des arbres d'expression sont "approuvés", mais d'un autre code n'est pas le cas.)

40voto

Eric Lippert Points 300275

Jon réponse est bonne. Je veux suivre sur Jon commentaire:

Je peux voir que si vous pouvez construire que l'expression de la programmation, qui vous permettra de contourner normal polymorphisme de l'extérieur plutôt que seulement à partir de l'intérieur de la classe elle-même (ce qui est le cas normal). C'est peut être la raison

Supposons que vous avez

public abstract class B // Prevent instantiation
{
    internal B() {} // Prevent subclassing outside the assembly. 
    public virtual void Dangerous() { ... } 
}
public sealed class D : B 
{ 
  public override void Dangerous() 
  { 
    if (!Allowed()) throw whatever;
    base.Dangerous();
  }

Il devrait y avoir aucun moyen pour que partiellement le code de confiance avec un D dans la main pour appeler B.Dangerous sur l'instance de D sans faire la vérification de la sécurité en D.Dangerous.

Le vérificateur CLR donc de restreindre vous d'effectuer une non-virtuel invocation (une base de l'invocation est bien sûr non virtuelle) sur une méthode virtuelle de l'extérieur de la hiérarchie de classe. En fait, il va même plus loin; on ne peut même pas réaliser qu'à partir d'une classe imbriquée dans D ! (Bien sûr, si votre programme est accordé le droit d'ignorer la vérification puis vous pouvez faire ce que vous voulez; vous pouvez déréférencement arbitraire des pointeurs vers la mémoire dans invérifiable code qui est bien pire que de faire un appel statique sur une méthode virtuelle.)

Lors de la conception des arbres d'expression, nous ne voulons pas traiter avec ce désordre problème de sécurité. La meilleure chose à faire est de simplement faire de l'ensemble de chose illégale.

Il y avait un certain nombre d'autres problèmes de sécurité avec des arbres d'expression qui ne pouvait pas être facilement résolu, mais ceux qui sont un sujet pour un autre jour.

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