The actual type cannot be inferred for a method that accepts an expression <Func>
I am writing a small library to parse the result sets of stored procedures (mostly a very specific type of ORM).
I have a class
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) { ... } } Here the IncludeList method indicates that result set no. resultSetIdx should be analyzed as if it consisted of TChild objects and was assigned to the property defined by the listProp expression (as an array).
I use it as follows:
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); This method works like a charm. So far so good.
I want to support various types of collections in addition to arrays. So, I am trying to add the following method:
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() { ... } However, when I try to use it as follows:
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); The C # compiler gives the error message `` Type arguments for the ParserSettings.IncludeList (...) method cannot be output. "
It works if I explicitly specify the types:
parentSettings.IncludeList<Child, List<Child>, int>( p => p.Children, p=> p.ParentId, c => c.ParentId, 1); but it spoils the target somewhat, making the challenge too difficult.
Is there any way to achieve type inference for this scenario?
I also noticed that the C # compiler's ability to infer types does not work โaround cornersโ.
In your case, you do not need any additional method, just rewrite Child[] as ICollection<TChild> , and the signature will correspond to arrays, lists, etc .:
public ParserSettings<TChild> IncludeList<TChild, TKey>( Expression<Func<T, ICollection<TChild>>> listProp, Func<T, TKey> foreignKey, Func<TChild, TKey> primaryKey, int resultSetIdx) { ... }