C# ReSharper:可能的无限继承
C# ReSharper: Possible infinite inheritance
为什么 ReSharper 在 IGeneric<TGeneric>
而不是 ISimple
接口上发出关于 可能无限继承 的警告?
// api
public interface INodeBase<TNode>
where TNode : INodeBase<TNode>
{
TNode Parent { get; set; }
List<TNode> Children { get; set; }
}
public interface INode<TValue>
: INodeBase<INode<TValue>>
{
TValue Value { get; set; }
}
public interface IBelongToNodeBase<TOwner>
where TOwner : INodeBase<TOwner>
{
TOwner Owner { get; set; }
}
// All good
public interface ISimple
: IBelongToNodeBase<INode<ISimple>>
{
}
// Possible infinite inheritance
public interface IGeneric<TGeneric>
: IBelongToNodeBase<INode<IGeneric<TGeneric>>>
{
}
会不会只是 ReSharper 智能感知的问题?这来自真实案例场景,代码编译和运行没有任何问题。
基于 link(由 René 提供),ReSharper 文档在泛型引用自身的三层嵌套之后提出了这个问题。
In a situation similar to the following:
class B<U>
{
}
class A<T> : B<A<A<T>>>
{
}
You effectively end up with the type A that inherits an infinitely recursive type B. As a result, your assembly will compile, but you will be unable to execute it. If you try, you will get an error message similar to the following:
Could not load type ‘ConsoleApplication1.A{{1' from assembly 'ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it has recursive generic definition.
为什么 ReSharper 在 IGeneric<TGeneric>
而不是 ISimple
接口上发出关于 可能无限继承 的警告?
// api
public interface INodeBase<TNode>
where TNode : INodeBase<TNode>
{
TNode Parent { get; set; }
List<TNode> Children { get; set; }
}
public interface INode<TValue>
: INodeBase<INode<TValue>>
{
TValue Value { get; set; }
}
public interface IBelongToNodeBase<TOwner>
where TOwner : INodeBase<TOwner>
{
TOwner Owner { get; set; }
}
// All good
public interface ISimple
: IBelongToNodeBase<INode<ISimple>>
{
}
// Possible infinite inheritance
public interface IGeneric<TGeneric>
: IBelongToNodeBase<INode<IGeneric<TGeneric>>>
{
}
会不会只是 ReSharper 智能感知的问题?这来自真实案例场景,代码编译和运行没有任何问题。
基于 link(由 René 提供),ReSharper 文档在泛型引用自身的三层嵌套之后提出了这个问题。
In a situation similar to the following:
class B<U>
{
}
class A<T> : B<A<A<T>>>
{
}
You effectively end up with the type A that inherits an infinitely recursive type B. As a result, your assembly will compile, but you will be unable to execute it. If you try, you will get an error message similar to the following:
Could not load type ‘ConsoleApplication1.A{{1' from assembly 'ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it has recursive generic definition.