csharp 允许创建注释(动态链接的对象/包装器)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 允许创建注释(动态链接的对象/包装器)相关的知识,希望对你有一定的参考价值。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace ObjectAnnotation
{
    public static class ObjectAnnotationExtensions
    {
        //TODO: Make thread safe
        static ConditionalWeakTable<object, List<object>> annotationsBySource 
            = new ConditionalWeakTable<object, List<object>>();
        static ConditionalWeakTable<object, object> sourceByAnnotation 
            = new ConditionalWeakTable<object, object>();

        static List<object> AnnotationsBySource(object source)
        {
            return annotationsBySource.GetOrCreateValue(source);
        }

        public static TAnnotation Annotation<TAnnotation>(this object source)
        {
            return source.Annotation<object, TAnnotation>(null);
        }

        public static TAnnotation Annotation<TAnnotation>(this object source
    , Func<object, TAnnotation> createIfNotExists)
        {
            return source.Annotation<object, TAnnotation>(createIfNotExists);
        }


        public static TAnnotation Annotation<TObject, TAnnotation>(this TObject source
            , Func<TObject, TAnnotation> createIfNotExists)
        {
            var wrappers = AnnotationsBySource(source);
            var wrapper = wrappers.OfType<TAnnotation>().FirstOrDefault();
            if (object.Equals(wrapper,default(TAnnotation)) && createIfNotExists != null)
            {
                wrapper = createIfNotExists(source);
                if (!object.Equals(wrapper,default(TAnnotation)))
                    wrappers.Add(wrapper);
                sourceByAnnotation.Remove(wrapper);
                sourceByAnnotation.Add(wrapper, source);
            }
            return wrapper;
        }

        public static void Annotation<TAnnotation>(this object source
    , TAnnotation newWrapper, bool removeOthers = true)
        {

            var wrappers = AnnotationsBySource(source);
            if (removeOthers)
            {
                var wrappersToRemove = wrappers.OfType<TAnnotation>().ToArray();
                wrappersToRemove.ForEach(w => source.AnnotationRemove(w));
            }
            if(!wrappers.Contains(newWrapper))
                wrappers.Add(newWrapper);
        }

        static void AnnotationRemove(this object source, object annotation)
        {
            var wrappers = AnnotationsBySource(source);
            wrappers.Remove(annotation);
            sourceByAnnotation.Remove(annotation);
        }



        public static IEnumerable<TAnnotation> Annotations<TAnnotation>(this object source)
        {
            var wrappers = annotationsBySource.GetOrCreateValue(source);
            return wrappers.OfType<TAnnotation>();
        }


        public static TTarget AnnotationTarget<TTarget>(this object annotation)
        {
            return (TTarget)annotation.AnnotationTarget();
        }
        public static object AnnotationTarget(this object annotation)
        {
            object res;
            if (sourceByAnnotation.TryGetValue(annotation, out res))
                return res;
            return null;
        }
        public static void AnnotationTarget<TAnnotation>(this TAnnotation annotation, object newSource)
        {
            var oldSource = annotation.AnnotationTarget();
            if (oldSource != null)
                oldSource.AnnotationRemove(annotation);

            newSource.Annotation(annotation, true);
        }
    }

}

以上是关于csharp 允许创建注释(动态链接的对象/包装器)的主要内容,如果未能解决你的问题,请参考以下文章

装饰器模式

spring 十三种模式之 -- 装饰器模式

设计模式 - 装饰器模式

设计模式—装饰器模式

java设计模式之 装饰器模式

java设计模式之 装饰器模式