c# - Generic LINQ to SQL Extension Methods on collection of various derived types -


i'm trying create generic extension method iqueryable<t>. t abstract player , iqueryable can contain concrete types goalkeeper , striker.

public abstract class player {     public string name { get; set; }     public string fouls { get; set; } }  public class goalkeeper : player {     public int saves { get; set; }  }  public class striker : player {     public int goals { get; set; } } 

the extension methods working (the simple ones) this:

public static iqueryable<goalkeeper> notperforming(this iqueryable<goalkeeper> goalkeepers) {     return goalkeepers.where(g => g.saves < goalkeepers.average(x => x.saves)); }  public static iqueryable<striker> notperforming(this iqueryable<striker> strikers) {     return strikers.where(g => g.goals < strikers.average(x => x.goals)); } 

which can use this:

var badgoalies = players.oftype<goalkeeper>().notperforming(); var badstrikers = players.oftype<striker>().notperforming(); 

so want query for players not performing well.

var badplayers = players.notperforming(); 

which can't seem work properly.

public static iqueryable<t> notperforming<t>(this iqueryable<t> players)     t : player {     // here? } 

i tried things like...

return players.oftype<striker>().notperforming()           .union(               players.oftype<goalkeeper>().notperforming()           ); 

which doesn't work.

what best practice way of doing -- , without leaving linq-to-sql because i'd keep chaining extension methods -- , keeping performance in mind?

you can create extension method , put there logic:

public static iqueryable<player> notperforming(this iqueryable<player> players) {     var notperforminggoalkeepers = players.notperforminggoalkeepers();     var notperformingstrikers = players.notperformingstrikers();      return notperforminggoalkeepers.cast<player>()         .concat(notperformingstrikers); }  public static iqueryable<goalkeeper> notperforminggoalkeepers(this iqueryable<player> players) {     var goalkeepers = players.oftype<goalkeeper>();     return goalkeepers.where(g => g.saves < goalkeepers.average(x => x.saves)); }  public static iqueryable<striker> notperformingstrikers(this iqueryable<player> players) {     var strikers = players.oftype<striker>();     return strikers.where(g => g.goals < strikers.average(x => x.goals)); } 

and use:

var badplayers = players.notperforming(); 

or approach:

public static iqueryable<player> notperforming<t>(this iqueryable<player> players) t : player {     if (typeof(t) == typeof(goalkeeper))     {         return players.oftype<goalkeeper>().notperforming();     }      if (typeof(t) == typeof(striker))     {         return players.oftype<striker>().notperforming();     }      return null; }  private static iqueryable<goalkeeper> notperforming(this iqueryable<goalkeeper> goalkeepers) {     return goalkeepers.where(g => g.saves < goalkeepers.average(x => x.saves)); }  private static iqueryable<striker> notperforming(this iqueryable<striker> strikers) {     return strikers.where(g => g.goals < strikers.average(x => x.goals)); } 

and use:

var badstrikers = players.notperforming<striker>(); var badgoalkeepers = players.notperforming<goalkeeper>();  var badplayers = players.notperforming<striker>()     .concat(players.notperforming<goalkeeper>()); 

Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

css - Can I use the :after pseudo-element on an input field? -