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

.net c# expression-trees

Question

J'appelais une méthode qui accepte l' Expression<Func<bool>> .

Dans le cadre de l'expression que je passais:

this.Bottom == base.lineView.Top

Le compilateur m'a donné une erreur qui

un arbre d'expression ne peut pas contenir d'accès de base

Alors j'ai simplement changé pour

this.Bottom == this.lineView.Top

parce que le député était protégé de toute façon et que cela fonctionne maintenant.

Mais cette erreur m'a vraiment eu: pourquoi diable cette base serait-elle un problème? Surtout si vous utilisez plutôt this fonctionnera mais que vous aurez le même résultat du point de vue de la syntaxe (la même variable est accessible)

Réponse acceptée

En regardant la documentation System.Linq.Expressions.Expression , je ne pense pas qu'il existe un type d'expression qui représente "l'accès des membres de base". N'oubliez pas que même si dans votre cas, cela signifiait la même this , dans d'autres cas, ce ne serait pas le cas:

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

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

Ici, cela représenterait un appel non virtuel à Object.ToString() (pour this ). Je ne vois pas comment cela serait représenté dans un arbre d'expression, d'où l'erreur.

Cela nous amène maintenant à la question évidente de savoir pourquoi il n’existe pas de représentation de l’invocation de membres de base non virtuels dans les arbres d’expression - j’ai peur de ne pouvoir répondre à cette partie ... bien que je puisse voir que si vous pouviez construire cette expression par programme, qui vous permettrait de contourner le polymorphisme normal de l'extérieur au lieu de seulement 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 d'appeler des méthodes de manière non virtuelle, mais c'est une autre affaire et j'ose dire qu'il existe des situations dans lesquelles les arbres d'expression sont "dignes de confiance" mais que les autres codes ne le sont pas.)


Réponse populaire

La réponse de Jon est correcte. Je veux faire suite au commentaire de Jon:

Je peux voir que si vous pouviez construire cette expression par programmation, cela vous permettrait de contourner le polymorphisme normal de l'extérieur plutôt que seulement 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 ayez

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 ne devrait y avoir aucun moyen pour un code partiellement de confiance avec un D en main d'appeler B.Dangerous sur l'instance de D sans effectuer la vérification de sécurité dans D.Dangerous .

Le vérificateur CLR vous empêche donc d'effectuer une invocation non virtuelle (une invocation de base est bien sûr non virtuelle) sur une méthode virtuelle en dehors de la hiérarchie de classes. En fait, ça va encore plus loin; vous ne pouvez même pas exécuter cela à partir d'une classe imbriquée dans D ! (Bien entendu, si votre programme a le droit de ne pas effectuer de vérification, vous pouvez faire ce que vous voulez; vous pouvez déréférencer des pointeurs arbitraires vers la mémoire dans du code non vérifiable, ce qui est bien pire que de passer un appel statique à une méthode virtuelle.)

Lorsque nous concevions des arbres d'expression, nous ne voulions pas traiter ce problème de sécurité complexe. La chose la plus facile à faire était simplement de rendre le tout illégal.

Un certain nombre d'autres problèmes de sécurité liés aux arborescences d'expression ne pouvaient pas être résolus aussi facilement, mais ceux-ci sont un sujet d'actualité.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi