美文网首页
C# Attribute based programming

C# Attribute based programming

作者: Brent姜 | 来源:发表于2017-08-03 14:41 被阅读20次

    今天在处理两个行情类(成为A和B)的时候,各自的代表同一个含义的属性,其属性名称并不相同,例如卖价4,A中和B中各自为APx4和AskPx4。如果要利用Interface限制显然不可取,因为这是两个层次上用于不同系统的类,牵一发而动全身。

    如果可以用DataContract的方式进行序列化、反序列化,也是一种方式,不过由于不同类中有各自特殊的字段,所以仍然需要进一步的其他处理。

    如果可以利用DataContract机制,但是将“DataContract”重命名为另外的Attribute,同时仅选择部分匹配属性字段进行Attribute化,仅针对这部分属性进行序列化、反序列化,是一个解决方案。

    How to control C# interface behavior using attribute. Sunday, November 25, 2007提到了“Attribute based programming”这个概念,暂且就这么用。

    Property Copying Between Two Objects using Reflection
    Read more at https://www.pluralsight.com/guides/microsoft-net/property-copying-between-two-objects-using-reflection#xyyRD1IhAmL8Gw87.99
    中的“the better way”章节介绍了使用自定义Attribute进行匹配限制。这当然不是最优性能的方案(IL manipulation才是最优),但是目前可用。

    接口

    public interface IMatchAttribute
    {
        string MatchPropertyName { get; }
    }
    

    属性类

    /// <summary>
    /// 用于在不同的行情数据类之间定义匹配的行情信息字段
    /// </summary>
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
    public class MatchQuotationAttribute : Attribute, IMatchAttribute
    {
        public string MatchPropertyName { get; private set; }
    
        public MatchQuotationAttribute(string quotationPropertyName)
        {
            MatchPropertyName = quotationPropertyName;
        }
    }
    

    扩展类

    /// <summary>
    /// see https://www.pluralsight.com/guides/microsoft-net/property-copying-between-two-objects-using-reflection
    /// </summary>
    /// <typeparam name="TAttrubute"></typeparam>
    public static class ObjectExtensionMethods
    {
        public static void MatchPropertiesFrom<TAttrubute>(this object self, object parent) where TAttrubute : IMatchAttribute
        {
            var childProperties = self.GetType().GetProperties();
            foreach (var childProperty in childProperties)
            {
                var attributesForProperty = childProperty.GetCustomAttributes(typeof(TAttrubute), true);
                var isOfTypeTAttrubute = false;
                TAttrubute currentAttribute = default(TAttrubute);
                foreach (var attribute in attributesForProperty)
                {
                    if (attribute.GetType() == typeof(TAttrubute))
                    {
                        isOfTypeTAttrubute = true;
                        currentAttribute = (TAttrubute) attribute;
                        break;
                    }
                }
                if (isOfTypeTAttrubute)
                {
                    var parentProperties = parent.GetType().GetProperties();
                    object parentPropertyValue = null;
                    foreach (var parentProperty in parentProperties)
                    {
                        if (parentProperty.Name == currentAttribute.MatchPropertyName)
                        {
                            if (parentProperty.PropertyType == childProperty.PropertyType)
                            {
                                parentPropertyValue = parentProperty.GetValue(parent);
                            }
                        }
                    }
                    childProperty.SetValue(self, parentPropertyValue);
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:C# Attribute based programming

          本文链接:https://www.haomeiwen.com/subject/ejdplxtx.html