2010-05-19 101 views
14

我想创建一个可以像一个属性可以使用自定义属性:如何通过自定义属性获取和修改属性值?

[TrimInputString] 
public string FirstName { get; set; } 

,这将是

private string _firstName 
public string FirstName { 
    set { 
    _firstName = value.Trim(); 
    } 
    get { 
    return _firstName; 
    } 
} 

功能等同所以基本上设定值,每次属性将被削减。

如何获取解析的值,修改该值,然后使用属性中的新值设置属性?

[AttributeUsage(AttributeTargets.Property)] 
public class TrimInputAttribute : Attribute { 

    public TrimInputAttribute() { 
    //not sure how to get and modify the property here 
    } 

} 
+0

我认为一个更好的方法是一个DataBinder:http://stackoverflow.com/a/1734025/7720 – Romias 2017-04-13 20:16:53

回答

6

这不是属性的工作方式。您不能从构造函数中访问任何属性。

如果你想做这个工作,你需要制作某种类型的处理器类,然后通过它传递对象,然后根据属性执行一些操作。可以在属性中定义要执行的操作(这里抽象的基本属性很方便),但仍然需要手动通过这些字段来应用操作。

1

正如Matti指出的,这不是属性的工作原理。但是,您可以使用PostSharp AOP framework来完成此操作,可能会覆盖OnMethodBoundaryAspect。但这不是微不足道的。

7

IAM这样做,不是非常有说服力的方式,但它的工作

试听课

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; } 

} 

写作属性为小写,其他人可以写在类似的方式

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; 
    } 
} 

不是非常优雅的方式,因为它实际上实现了验证属性b它可以工作

+0

这当然,只有当你的程序在某些点运行验证对象时才有效。有趣的黑客攻击,但我不会在生产代码中使用它。 – 2015-07-02 19:00:38

+1

也许你会想'返回ValidationResult.Success;' – Nikola 2017-08-23 11:29:11

0

这可以用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(); 

你可以看到更多的文档here

+0

不判断解决方案本身。但是我觉得选择的命名空间会让人误解。我的第一印象是它是.Net框架本身的一部分。虽然不是。为什么不用RoyDukkey.ComponentModel.Mutations来启动命名空间,同样也要称赞你的名字。 – 2017-02-28 08:09:38

+0

我同意。这最初是作为一项建议而建立的,但是此后一直关闭。我还没有时间将命名空间改为更合适的东西。 – roydukkey 2017-03-01 01:33:33