С#: что такое постоянное выражение?

Я работаю с атрибутами в данный момент. Я часто сталкиваюсь с ошибкой «Аргумент атрибута должен быть постоянным выражением, выражением typeof или выражением создания массива типа параметра атрибута». Я действительно не знаю, что означает «постоянное выражение».

Было бы очень полезно иметь возможность передать Func<MyType, bool> атрибуту (для использования кодом, который выполняется, когда атрибут присутствует). Но увы, нет. Я не понимаю, почему этот тип нельзя поместить в метаданные сборки, что, как я полагаю, является причиной того, что я не могу передать его в атрибут.

Может ли кто-нибудь дать мне какие-либо идеи?


person David    schedule 04.05.2012    source источник


Ответы (4)


Компилятор должен иметь возможность создавать атрибуты во время компиляции, поскольку они встроены в вашу сборку с их фактическими данными (они создаются компилятором и сериализуются в выходной файл). Вот почему вам нужно постоянное выражение.

В основном вы можете использовать все основные типы данных (такие как int, bool, string и т. д.). Вы также можете использовать выражения typeof, потому что они будут преобразованы в токены метаданных, идентифицирующие тип, что хорошо во время компиляции.

Возможно, вы сможете поместить концепцию вашего Func<MyType, bool> в интерфейс, который реализуют ваши типы. Или в отдельный класс обработчика, который вы можете передать своему атрибуту, используя выражение typeof(MyHandlerClass).

person Botz3000    schedule 04.05.2012
comment
Это в основном делегат, который я предложил ниже. - person Styxxy; 04.05.2012

Константные выражения — это значения, определяемые исключительно во время компиляции, включая конкатенацию строк других константных выражений, арифметические операции и т. д.

Так, например, "" является постоянным выражением, а String.Empty - нет.

String — единственный ссылочный тип, поддерживающий ненулевое константное выражение. Для типов значений примитивные типы (int и т. д.) и decimal поддерживают константные выражения... хотя вы не можете использовать decimal в атрибутах, так как это не примитив в CLR. (Вы даже не можете указать decimal в качестве типа параметра в конструкторе атрибута.)

Дополнительные сведения см. в разделе 7.19 спецификации C# 4.

person Jon Skeet    schedule 04.05.2012
comment
Не разрешено использовать decimal. Подробнее здесь: docs.microsoft.com/en-us/dotnet/csharp /misc/cs0182 - person tomwesolowski; 23.01.2018
comment
@tomwesolowski: Отредактировано, хотя было бы полезно сказать, что вы имели в виду. - person Jon Skeet; 23.01.2018
comment
@JonSkeet: Спасибо за ответ. Любить это. - person Morteza Azizi; 26.02.2019

Атрибуты в C# являются артефактами времени компиляции, поэтому для создания они должны иметь постоянные параметры/маркеры/что угодно...

Возможны попытки сделать то, что вы, я полагаю, собираетесь сделать:

Динамические атрибуты в C#

person Tigran    schedule 04.05.2012
comment
Спасибо за очень интересную ссылку. - person David; 04.05.2012

Константное выражение — это выражение, которое можно полностью вычислить во время компиляции.

http://msdn.microsoft.com/en-us/library/aa691319(v=vs.71).aspx (старая статья, но все еще актуальная)

person Tim Medora    schedule 04.05.2012