Ответ 1
спецификация языка С#, §10.3 говорит (внимание мое):
Если требуется символическое имя для постоянного значения, но когда тип этого значения не разрешен в объявлении константы или когда значение не может быть вычислено во время компиляции константным выражением, a Поле
readonly
(Раздел 10.4.2) может использоваться вместо.
Раздражающе, это усугубляется тем фактом, что атрибуты также имеют определенные ограничения - см. спецификацию языка С#, §17.2 (опять же, ):
Выражение E является выражением атрибута-аргумента, если все следующие утверждения верны:
Тип E - это тип параметра атрибута (раздел 17.1.3).
Во время компиляции значение E можно решить одним из следующих:
Постоянное значение.
Объект System.Type.
Одномерный массив атрибутов-аргументов-выражений.
Где §17.1.3: "Типы параметров атрибутов" говорит 1:
Типы позиционных и именованных параметров для класса атрибута ограничены типами атрибутных параметров, которые:
- Один из следующих типов:
bool
,byte
,char
,double
,float
,int
,long
,short
,string
.- Тип
object
.- Тип
System.Type
.- Тип перечисления, если он имеет общедоступную доступность, и типы, в которых он вложен (если есть), также имеют общедоступную доступность (§17.2).
- Одномерные массивы вышеуказанных типов.
1: цитируемый текст относится к более старой версии спецификации С# - в версии С# 5.0, упоминаются четыре дополнительных типа: sbyte
, uint
, ulong
и ushort
.
Другими словами, лучшее, что вы можете сделать, это что-то вроде:
[TestFixture]
public class SomeObjectTests {
private static readonly SomeObject item0 = new SomeObject(0.0);
private static SomeObject getObject(string key) {
if ( key == "item0" )
return item0;
throw new ArgumentException("Unknown key");
}
[TestCase("item0", ExpectedResult = 0.0)]
public double TestSomeObjectValue(string key) {
SomeObject so = getObject(key);
return so.Value;
}
[TestCase("item0", ExpectedResult = "0.0")]
public string TestSomeObjectValueString(string key) {
SomeObject so = getObject(key);
return so.ValueString;
}
}
Таким образом, аргументы атрибутов являются константой времени компиляции, а метод getObject
может обрабатывать получение экземпляра SomeObject
.