复杂的泛型需要一些怪异的转换才能运行

时间:2018-11-21 09:21:10

标签: c# generics

围绕通用性,我建立了一个简单的社交网络模型,该模型基于人与人之间的关系。

所有这些都存储在容器中。

对于每个容器,我希望能够添加一些验证以检查某些特定约束。

这里可能是过于复杂的模型,但是正如我所说的,我在玩通用性,所以它是故意的:

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#通用引擎的极限?

0 个答案:

没有答案