代码之家  ›  专栏  ›  技术社区  ›  Aaron Fischer

基类如何引用一个超类型并仍然编译?

c#
  •  0
  • Aaron Fischer  · 技术社区  · 14 年前

    这个类是如何编译的?

    public class ReflectionHelper
    {
        public static IReflectionHelper CreateHelper( object subject )
        {
            return ( IReflectionHelper )Activator.CreateInstance( typeof( ReflectionHelper<> ).MakeGenericType( GetFirstGenericArgument( subject ) ) );
        }
        public static Type GetFirstGenericArgument( object subject )
        {
            return subject.GetType().GetGenericArguments()[ 0 ];
        }
    }
    
    public class ReflectionHelper<T> : ReflectionHelper, IReflectionHelper where T : new()
        {}
    

    请注意ReflectionHelper <T> 继承自ReflectionHelper,它引用ReflectionHelper的类型<&燃气轮机; 出于某种原因,我期望出现循环引用编译错误。

    2 回复  |  直到 14 年前
        1
  •  5
  •   Jon Skeet    14 年前

    你必须详细说明你的“某些理由”,让我们来解释为什么这实际上不是一个问题。在.NET中,循环引用无处不在——只要它在同一程序集中,它们就不是问题。对于更简单的非通用示例:

    // Compiles with no problem
    class Foo
    {
        Bar other;
    }
    
    class Bar
    {
        Foo other;
    }
    

    (实际上有两个循环 BCL中的引用。。。但那只是肮脏和邪恶。)

        2
  •  4
  •   Eric Lippert    14 年前

    很好,谢谢。

    出于某种原因,我期望出现循环引用编译错误。

    我不知道你为什么会这么想。出现循环参考误差的情况有:

    1) 涉及基类循环的循环引用:

    class C : B {}
    class B : C {} 
    

    有趣的是,对C#2.0规范的严格阅读实际上并没有带来什么好处

    class C : C {}
    

    3) 类型参数约束中的循环:

    class C<T, U> where T : U 
                  where U : T
    

    enum E { A = B, B = A }
    

    还请注意,外部类从内部类继承是非法的,尽管反向继承是合法的。

    这些都是我马上想到的。不过我想我少了一两个。

    在C#cycle探测器中存在一些已知的错误。例如,编译器将此标记为循环错误,即使它不是:

    class November<T> {}
    class Romeo : November<Romeo.Sierra.Tango>
    {
        class Sierra { class Tango { } }
    }
    

    但是,您的案例中肯定没有循环。你为什么相信有一个循环?