Как получить и изменить значение свойства через пользовательский атрибут?
Я хочу создать пользовательский атрибут, который можно использовать в качестве свойства:
[TrimInputString]
public string FirstName { get; set; }
который будет функциональным эквивалентом
private string _firstName
public string FirstName {
set {
_firstName = value.Trim();
}
get {
return _firstName;
}
}
Таким образом, каждый раз, когда свойство установлено, значение будет обрезано.
Как получить синтаксическое значение, изменить это значение и затем установить свойство с новым значением all из атрибута?
[AttributeUsage(AttributeTargets.Property)]
public class TrimInputAttribute : Attribute {
public TrimInputAttribute() {
//not sure how to get and modify the property here
}
}
Ответы
Ответ 1
Это не то, как работают атрибуты. Вы не можете получить доступ к тому, с каким атрибутом прикреплен внутри конструктора.
Если вы хотите выполнить эту работу, вам нужно будет сделать какой-то класс процессора, которому вы передаете объект, который затем проходит через поля и что-то делает в зависимости от атрибутов. Операция, которую нужно выполнить, может быть определена внутри атрибута (здесь используется атрибут абстрактного базового атрибута), но вам все равно нужно пройти через поля вручную, чтобы применить операцию.
Ответ 2
Я делаю это, не очень убедительно, но его рабочий
демонстрационный класс
public class User
{
[TitleCase]
public string FirstName { get; set; }
[TitleCase]
public string LastName { get; set; }
[UpperCase]
public string Salutation { get; set; }
[LowerCase]
public string Email { get; set; }
}
Запись атрибута для LowerCase, другие могут быть написаны аналогичным образом
public class LowerCaseAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
//try to modify text
try
{
validationContext
.ObjectType
.GetProperty(validationContext.MemberName)
.SetValue(validationContext.ObjectInstance, value.ToString().ToLower(), null);
}
catch (System.Exception)
{
}
//return null to make sure this attribute never say iam invalid
return null;
}
}
Не очень элегантный способ, поскольку он фактически реализует атрибут Validation, но он работает
Ответ 3
Как отметил Матти, это не так, как работают атрибуты. Тем не менее, вы можете использовать PostSharp AOP framework для этого, возможно, переопределяя OnMethodBoundaryAspect. Но это не тривиально.
Ответ 4
Это можно сделать с помощью Dado.ComponentModel.Mutations.
public class User
{
[Trim]
public string FirstName { get; set; }
}
// Then to preform mutation
var user = new User() {
FirstName = " David Glenn "
}
new MutationContext<User>(user).Mutate();
Вы можете увидеть дополнительную документацию здесь.