2013-03-15 70 views
4

我正在编写一个小型库来解析存储过程的结果集(基本上,非常特殊的一种ORM)。无法为接受方法推断实际类型<Func>

我有类

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); 

但这是有点失败的目的拨打电话太复杂。

有没有一种方法来实现这种情况下的类型推断?

+0

@HamletHakobyan,我要创建分配与新物业映射期间的收集值。一些东西沿着: 'var childrenBuckets = childrenResultSet.ToLookup(primaryKey); (父parentResultSet){ var value = childrenBuckets [foreignKey(parent)]; setProperty(parent,new TList {value}); }' 如果我不能通过'new'创建值' – 2013-03-15 06:29:22

+0

'作为@devio提及的'ICollection',将会变得更加困难。我对这个问题的'理论上的'方面很感兴趣,在期望类型引用能够解决这个问题时我没有看错。 – 2013-03-16 13:14:10

回答

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) { 
      ... 
     } 
+1

有趣。你有没有参考类型推断这样的陷阱? – 2013-03-15 08:05:00

+0

我想在数据解析期间在场景后面创建集合。这意味着理想情况下我需要特定类型(和“new()”约束)或者为每个属性使用Activator.CreateInstance(我宁愿避免)。 – 2013-03-15 17:03:05

+0

传递一个ICollection工厂,而不是暗示集合类型 – devio 2013-03-15 17:36:35

相关问题