无法推断接受Expression <func> </func>的方法的实际类型

时间:2013-03-15 06:14:40

标签: c# type-inference expression

我正在编写一个小型库来解析存储过程的结果集(基本上是非常特殊的ORM)。

我有课

class ParserSetting<T> // T - type corresponding to particular resultset
{
    ...
    public ParserSettings<TChild> IncludeList<TChild, TKey>(
        Expression<Func<T, TChild[]>> listProp,
        Func<T, TKey> foreignKey,
        Func<TChild, TKey> primaryKey,
        int resultSetIdx)
    { ... }
}

此处方法IncludeList指定结果集号。应该解析resultSetIdx,好像它由TChild个对象组成,并分配给由listProp表达式定义的属性(作为数组)。

我正在使用它如下:

class Parent
{
   public int ParentId {get;set;}
   ...
   public Child[] Children{get;set;}
}

class Child
{
   public int ParentId {get;set;}
   ...
}
ParserSettings<Parent> parentSettings = ...;
parentSettings.IncludeList(p => p.Children, p=> p.ParentId, c => c.ParentId, 1);

此方法可作为魅力。到目前为止,非常好。

除了数组之外,我还想支持不同类型的集合。所以,我正在尝试添加以下方法:

    public ParserSettings<TChild> IncludeList<TChild, TListChild, TKey>(
        Expression<Func<T, TListChild>> listProp,
        Func<T, TKey> foreignKey,
        Func<TChild, TKey> primaryKey,
        int resultSetIdx)
    where TListChild: ICollection<TChild>, new()
    { ... }

然而,当我尝试按如下方式使用它时:

class Parent
{
   public int ParentId {get;set;}
   ...
   public List<Child> Children{get;set;}
}

class Child
{
   public int ParentId {get;set;}
   ...
}
ParserSettings<Parent> parentSettings = ...;
parentSettings.IncludeList(p => p.Children, p=> p.ParentId, c => c.ParentId, 1);

C#编译器发出错误消息“”无法推断方法ParserSettings.IncludeList(...)的类型参数“。

如果我明确指定类型,它可以工作:

parentSettings.IncludeList<Child, List<Child>, int>(
    p => p.Children, p=> p.ParentId, c => c.ParentId, 1);

但这有点挫败了打电话过于复杂的目的。

有没有办法为这种情况实现类型推断?

1 个答案:

答案 0 :(得分:0)

我还注意到C#编译器推断类型的能力不适用于“拐角”。

在您的情况下,您不需要任何其他方法,只需将Child[]重写为ICollection<TChild>,签名将匹配数组,列表等:

    public ParserSettings<TChild> IncludeList<TChild, TKey>(
        Expression<Func<T, ICollection<TChild>>> listProp,
        Func<T, TKey> foreignKey,
        Func<TChild, TKey> primaryKey,
        int resultSetIdx) {
            ...
        }