2012-05-04 3 views
4

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

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

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

ответ

3

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

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

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

+0

Это в основном делегат, который я предложил ниже. – Styxxy

2

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

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

Dynamic Attributes in C#

+0

Благодарим вас за очень интересную ссылку. – David

7

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

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

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

Дополнительную информацию см. В разделе 7.19 спецификации C# 4.

+0

Нельзя использовать 'decimal'. Подробнее здесь: https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs0182 – tomwesolowski

+0

@tomwesolowski: Отредактировано, хотя было бы полезно сказать, о чем вы говорили. –

Смежные вопросы