c# - 复杂的泛型需要一些奇怪的铸件才能运行
问题描述
玩弄通用性,我建立了一个简单的社交网络模型,基于人和他们之间的关系。
所有这些都存储在一个容器中。
对于每个容器,我希望能够添加一些验证来检查一些特定的约束。
这是可能过于复杂的模型,但如前所述,我正在玩通用性,所以它是故意的:
public interface IContainer<TPerson, TRelation>
where TRelation : IRelation<TPerson>
{
IReadOnlyCollection<TPerson> Persons { get; }
IReadOnlyCollection<TRelation> Relations { get; }
}
public class DefaultContainer<TPerson, TRelation>
: IContainer<TPerson, TRelation>
where TRelation : IRelation<TPerson>
{
private readonly HashSet<TPerson> _persons;
private readonly List<TRelation> _relations;
//...
}
public class DummyValidator<TContainer, TPerson, TRelation>
: IValidator<TContainer, TPerson, TRelation>
where TContainer : IMutableContainer<TPerson, TRelation>
where TRelation : IRelation<TPerson>
{
public bool CanAddRelations(TContainer container, IEnumerable<TRelation> relations)
{
// guard clauses
return true; // whatever
}
public bool CanCreate(IEnumerable<TPerson> persons, IEnumerable<TRelation> relations)
{
// guard clauses
return CanAddRelations(new DefaultContainer<TPerson, TRelation>(), relations);
}
//...
}
[Fact]
public void Test()
{
var sut = new DummyValidator<IContainer<int, IRelation<int>>, int, IRelation<int>>();
sut.CanCreate(Enumerable.Empty<int>(), Enumerable.Empty<IRelation<int>>());
}
看一下类的CanCreate
方法DummyValidator
。它创建一个新容器(实现TContainer
):
return CanAddRelations(new DefaultContainer<TPerson, TRelation>(), relations);
所以一切都应该没问题,据我所知。但是编译器抱怨说:
无法从“Alcuin.Graph.Containers.DefaultContainer”转换为“TContainer”
我的问题是:为什么它会抱怨这一点,即使每个通用参数都被描述并且总是等效的?
所以我尝试了一些明确的演员来调查:
return CanAddRelations((TContainer)new DefaultContainer<TPerson, TRelation>(), relations);
和
return CanAddRelations((IMutableContainer<TPerson, TRelation>)new DefaultContainer<TPerson, TRelation>(), relations);
都失败了,但是:
return CanAddRelations((TContainer)(IMutableContainer<TPerson, TRelation>)new DefaultContainer<TPerson, TRelation>(), relations);
编译并正确运行...
任何人都可以阐明这里发生的事情吗?我错过了一些明显的东西吗?我是否达到了 C# 通用引擎的极限?