Может ли класс наследовать от LambdaExpression в .NET? Или это не рекомендуется? - PullRequest
3 голосов
/ 20 февраля 2010

Рассмотрим следующий код (C # 4.0):

public class Foo : LambdaExpression { }

Это приводит к следующей ошибке времени разработки:

Foo does not implement inherited abstract member
System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller)

Нет абсолютно никаких проблем с public class Foo : Expression { }, но из любопытства и ради обучения я искал в Google System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller) и угадаю, что: ноль результатов вернулось (когда вы в последний раз видели это?) , Само собой разумеется, я нигде не нашел никакой документации по этому методу.

Как я уже сказал, можно легко унаследовать от Expression; с другой стороны, LambdaExpression, хотя и не помечен как sealed (Expression<TDelegate> наследуется от него), похоже, предназначен для предотвращения наследования от него. Это действительно так? Кто-нибудь знает, о чем этот метод?

РЕДАКТИРОВАТЬ (1): дополнительная информация, основанная на первых ответах. Если вы попытаетесь реализовать Accept, редактор (C # 2010 Express) автоматически выдаст следующую заглушку:

protected override Expression Accept(System.Linq.Expressions.ExpressionVisitor visitor)
{
    return base.Accept(visitor);
}

Но вы все равно получаете ту же ошибку. Если вы попытаетесь использовать параметр типа StackSpiller напрямую, компилятор выдаст другую ошибку: System.Linq.Expressions.Compiler.StackSpiller is inaccessible due to its protection level.

EDIT (2): Исходя из других ответов, наследование от LambdaExpression невозможно, поэтому вопрос о том, рекомендуется он или нет, становится неактуальным. Интересно, в таких случаях сообщение об ошибке должно быть Foo cannot implement inherited abstract member System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller) because [reasons go here]; текущее сообщение об ошибке (как доказывают некоторые ответы), кажется, говорит мне, что все, что мне нужно сделать, это реализовать Accept (что я не могу сделать).

Ответы [ 4 ]

7 голосов
/ 20 февраля 2010

Я только что посмотрел на класс LambdaExpression в .NET 3.5, используя Reflector, и класс имеет только конструктор internal. Когда я пробую ваш код, я получаю сообщение об ошибке «Тип« System.Linq.Expressions. LambdaExpression »не имеет определенных конструкторов», поэтому в .NET 3.5 этого сделать нельзя (оставляя в стороне вопрос, будет ли это полезно для сделай это).

В .NET 4.0 ведет себя так, как вы описали. Однако метод Accept - это internal, как и тип StackSpiller. Это снова означает, что вы просто не можете сделать это (хотя это не ясно из сообщения об ошибке компилятора). Стоит отметить, что класс все еще имеет только конструктор internal в .NET 4.0. Компилятор находит только другую причину, по которой вы не можете переопределить его (и больше об этом не беспокоитесь).

РЕДАКТИРОВАТЬ: Что касается типа StackSpiller - он внутренний, поэтому вам не нужно беспокоиться об этом. Однако, похоже, что тип происходит из DLR, который является компонентом .NET 4.0, который теперь обрабатывает компиляцию лямбда-выражений (а также C # 4 dynamic). В любом случае, DLR является открытым исходным кодом, поэтому вот что говорит краткий комментарий об этом типе:

Переписывание выражений для разделения стека CLR на временные переменные чтобы гарантировать некоторые свойства генерации кода, для пример того, что мы всегда вводим блок try в пустом стеке.

Это означает, что он используется для некоторой предварительной обработки лямбда-выражений, когда они компилируются с использованием метода Compile. Вы можете получить исходный код от CodePlex .

4 голосов
/ 20 февраля 2010

Сообщение об ошибке означает, что LambdaExpression сам по себе является абстрактным классом. Вам нужно либо предоставить свое тело для абстрактного метода Accept, либо объявить Foo как абстрактный.

Однако, список LambdaExpression членов на MSDN не содержит списка Accept.

2 голосов
/ 20 февраля 2010

Не рекомендуется и не рекомендуется. Тип LambdaExpression имеет несколько внутренних абстрактных членов и внутренний конструктор. Это не позволяет вам извлечь его из другой сборки, если только они не являются отношениями друзей (которых в данном случае нет)

2 голосов
/ 20 февраля 2010

Что ж, ошибка в основном говорит нам о том, что LambdaExpression является абстрактным классом, что означает, что для его получения вам необходимо реализовать все абстрактные члены. В этом случае метод Accept.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...