Кстати, этот код действителен только для версии языка C#-11
(т. е.: создайте проект платформы Net 8.0 или более поздней версии для тестирования).
Не является ли проблема кода ниже ограничения нового синтаксиса C#
(что было бы печально, потому что этот вариант использования, я думаю, один из самых востребованных)?
Или я ошибаюсь в синтаксисе ?
Моя цель — использовать позже «IDynamicEnum» для типа, известного только во время выполнения (с использованием отражения). Но я не уверен, предназначен ли метод статического интерфейса для использования, как я пытаюсь сделать здесь, или он предназначен только для случая, когда T всегда известен во время компиляции. я просто играю с C# 11.
Я знаю, что могу полностью удалить интерфейс IDynamicEnum и использовать что-то вроде typeof(IDynamicEnum).MakeGenericType(the_type_is_got_by_reflection), но этот вопрос кажется интересным в любом случае.
Код: Выделить всё
/// Tag a class that acts as an enum class (in the java way)
public interface IDynamicEnum
{
string Name { get; }
ulong Value { get; }
static abstract IEnumerable GetAllValues();
}
///
public interface IDynamicEnum : IDynamicEnum
where T : class, IDynamicEnum
{
// A better signature: We strongly type
new static abstract IEnumerable GetAllValues();
// I would like to automatically implement the non generic method...
// To do that, intuitively i would like to write this line
// which is kind of a "return type covariance on static interface method"
// But sadly it gives error CS8926
//static IEnumerable IDynamicEnum.GetAllValues() => GetAllValues();
}
public class MyDynamicEnum : IDynamicEnum
{
public string Name { get; }
public ulong Value { get; }
public static MyDynamicEnum Foo { get; } = new MyDynamicEnum("Foo", 1);
public static MyDynamicEnum Bar { get; } = new MyDynamicEnum("Bar", 2);
public static MyDynamicEnum Baz { get; } = new MyDynamicEnum("Baz", 3);
public static IEnumerable AllValues { get; } = new[] { Foo, Bar, Baz };
protected MyDynamicEnum(string name, long value) { Name = name; Value = value; }
public static IEnumerable GetAllValues() => AllValues;
// So I could get rid of this annoying / duplicated line
static IEnumerable IDynamicEnum.GetAllValues() => AllValues;
}
Настоящее применение — это перечисление, неизвестное заранее, например, для обработки всего небольшого набора значений, связанных с синтаксическим анализом. Файлы csproj/sln:
- Конфигурация («Отладка», «Выпуск», пользовательские настройки, определенные пользователями... невозможно узнать их заранее)< /li>
Платформы («x86», x64", "Любой процессор", далее как много разных надписей, с пробелом, с "ЦП" или "ЦП") - Рамка: Содержит много разных значений. стандартные (которые я хочу обрабатывать): «net48», ..., «net8.0», но также много необычных/редких значений, которые я не хочу обрабатывать, например «net7.0-tvos» . У них также можно много писать (с точкой). или нет...)
Итак… ок, имя «DynamicEnum», возможно, неправильное. но я хотел задать простой вопрос, а не вступать в дискуссию о проблеме XY.
Более того, я хочу, чтобы этот код работал как в net48, так и в net8.0, поэтому я воспользуюсь преимуществами компилятора. потому что он проверит компиляцию кода для bioth net8.0 и net4.8. Таким образом, ограничение статического метода дает мне большую вероятность, метод также существует для net48 (я не знаю, нет гарантии, но больше, чем если бы разработчик ожидал, что прочитает XML-документ...)
Подробнее здесь: https://stackoverflow.com/questions/793 ... ntation-of