Вот один из способов сделать то, что вы просите, но он не особенно масштабируемый и требует кучу ручного кода, чтобы начать работу, но может привести вас к пути к тому, чего вы пытаетесь достичь.Предполагая, что у нас есть атрибут, похожий на этот, который принимает в своем конструкторе строковый массив:
public class MyAttrAttribute : Attribute
{
public string[] AllowedValues { get; }
public MyAttrAttribute(params string[] values)
{
AllowedValues = values;
}
}
Вы можете изменить свое поле на свойство с полем поддержки.Это позволяет вам переопределить метод set
и выполнить там проверку:
private string _testArg;
[MyAttr("TestArg1", "TestArg2")] //check that some string equals TestArg1/TestArg2
public string TestArg
{
get => _testArg;
set
{
var allowedValues = this.GetType() //Get the type of 'this'
.GetProperty(nameof(TestArg)) // Get this property
.GetCustomAttribute<MyAttrAttribute>() // Get the attribute
.AllowedValues; //Get the allowed values specified in the attribute
if(!allowedValues.Contains(value))
{
throw new ArgumentOutOfRangeException(nameof(value),
$"The value '{value}' is not allowed");
}
_testArg = value;
}
}
Сказав все это, я твердо верю, что есть лучший способ добиться того, что вы просите.Например, если вы ограничены минимальным набором значений, то enum
почти наверняка будет лучшим вариантом, чем строка.