c#中的奇异递归模式

奇异递归模式,Curiously Recurring Template Pattern (CRTP) ,作用是能使父类中能够使用子类的信息。下面是我对这个问题的分析过程。

按照一般的继承关系,父类是无法访问到子类的,所以很自然的想到了c#中的泛型,将子类作为父类的泛型版本中的<T>,就能通过父类中的<T>来访问子类信息。

class App
{
    static void Main()
    {
        foreach (var str in DerivedA.NowClsMemberInfo)
        {
            Console.WriteLine(str);
        }
        Console.ReadLine();
    }
}

public class BaseA<T>
{
    public static IEnumerable<string> NowClsMemberInfo
    {
        get
        {
            foreach (var memberInfo in typeof (T).GetMembers())
            {
                yield return memberInfo.Name;
            }
        }
    }
}

public class DerivedA : BaseA<DerivedA>
{
    public string StrA { get; set; }
}
DerivedA : BaseA<DerivedA>看着有些别扭,T1:BaseA<T2>中的T2,又要满足T2:BaseA<T3>,有点递归的意思。
这里的T,我们是当作子类来用的,所以必须加一个约束,继承自父类,即:
public class BaseA<T> where T : BaseA<T>
{
    public static IEnumerable<string> NowClsMemberInfo
    {
        get
        {
            foreach (var memberInfo in typeof (T).GetMembers())
            {
                yield return memberInfo.Name;
            }
        }
    }
}

这是为了避免被人以比如BaseA<string>的形式调用,如果父类中的T(子类)用到了父类中的成员,类似于BaseA<string>的类就会出现编译错误,如:

public class BaseA<T> 
{
    public static IEnumerable<string> NowClsMemberInfo
    {
        get
        {
            foreach (var memberInfo in typeof (T).GetMembers())
            {
                yield return memberInfo.Name;
            }
        }
    }

    public T InstanceNow { get; set; }

    public void DoSomething()
    {
        InstanceNow.DoSomething();
    }
}
所以:
public class BaseA<T> where T : BaseA<T>
{
    public static IEnumerable<string> NowClsMemberInfo
    {
        get
        {
            foreach (var memberInfo in typeof (T).GetMembers())
            {
                yield return memberInfo.Name;
            }
        }
    }

    public T InstanceNow { get; set; }

    public void DoSomething()
    {
        InstanceNow.DoSomething();
    }
}

参照的资料:

http://zpbappi.com/curiously-recurring-template-pattern-in-csharp/

https://www.zhihu.com/question/27421302

 
posted @ 2017-09-30 15:44  阿珑  阅读(621)  评论(0编辑  收藏  举报