【问题标题】:Appropriate use of custom attributes?适当使用自定义属性?
【发布时间】:2009-05-22 14:14:07
【问题描述】:

我有一个 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”。你认为属性是解决这个问题的好方法吗?还有一个问题,如果我确实通过属性解决了这个问题,我是否可能会造成巨大的性能瓶颈,或者使用属性不是真正的性能问题。

【问题讨论】:

    标签: c# .net performance reflection attributes


    【解决方案1】:

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

    有一些方法可以提高反射的性能,但它们是相当先进的。

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        我最终编写了以下代码。

        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 查询通常比一些内存操作慢得多,所以我期待结果. :)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-05
          • 1970-01-01
          • 1970-01-01
          • 2011-06-25
          • 1970-01-01
          相关资源
          最近更新 更多