适当使用自定义属性?

时间:2009-05-22 14:14:08

标签: c# .net performance reflection attributes

我有一个DataContract类,我必须用我们公司的Active Directory中的值来填充。

[DataContract(Namespace = Global.Namespace)]
public class UserProfile
{
    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    public string EmployeeID { get; private set; }

    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    public string GivenName { get; private set; }

    ...

    public static readonly string[] PropertiesToLoad = new[] { "EmployeeID", "GivenName" };
}

我正在考虑制作一个自定义属性来装饰我的属性,这样从AD填充我的对象的代码就不需要对映射进行硬编码,而是我可以装饰属性来自动填充对象

从长远来看,我也可以摆脱这个“PropertiesToLoad”。你认为属性是解决这个问题的好方法吗?另一个问题是,如果我通过属性来解决这个问题,我是否可能会产生巨大的性能瓶颈,或者使用属性并不是真正的性能问题。

3 个答案:

答案 0 :(得分:3)

使用反射和属性 比编译为IL的常规C#慢,但问题是:你做了多少?如果你没有做很多,你就不会注意到它。

有提高反射性能的方法,但它们非常先进。

这似乎是一种指定映射的合理方式(并且与大多数序列化和持久性框架相当 - 尽管通常也提供没有属性的单独API)。

对于(in)适当的用途,请参阅Eric Lippert's blog

答案 1 :(得分:1)

我喜欢使用属性来解决这种问题,因为它有助于在代码中清楚地表明属性以某种方式被使用。将PropertiesToLoad放在一个地方(如上例所示)或属性声明点之间需要进行权衡。我倾向于发现使用属性有助于代码维护,因为如果删除或修改属性,我不必追捕更改。

至于性能,是的,它会导致性能下降,但不会很大。它是可测量的,但除非这是性能关键代码,否则您可能不会注意到。即使在那一点上,我猜你会发现更大的问题。如果属性反射成为问题,则可以通过使用缓存或其他方法来降低性能影响。

答案 2 :(得分:1)

我最后编写了以下代码。

public class UserProfile
{
    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public string EmployeeID { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public string GivenName { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty("SN")]
    public string Surname { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public string Company { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public string Department { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty("CN")]
    public string UserName { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty("Mail")]
    public string Email { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public LanguageType Language { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    public DateTime? NextPasswordChangeDate { get; set; }
}

然后我可以使用反射来获取旧的“PropertiesToLoad”,它本身几乎无害,因为我之后只使用一次反射来填充数组,我不再需要调用GetProperties了。

唯一还有待测试的是,如果我可以足够快地从SearchResult中填充对象 - 但是,tbh,AD查询通常比一些内存中操作慢,所以我期待结果。 :)