I have a helper class that I am using to return the selected items in a number of IEnumerable POCO collection but I'm not happy with the implementation. One of the reasons for using this method is that the collections area returned by RIA services as ReadOnlyObservableCollections and I don't believe they support LINQ but may be wrong.
Is there a way to refactor these three methods using generics? Are there any other improvements that I can make?
public class ModelHelper : IModelHelper
{
public IList<Int32> GetSelectedResults(IEnumerable<FaultAuditScoresDto> scores)
{
IList<Int32> selected = new List<Int32>();
foreach (FaultAuditScoresDto s in scores)
{
if (s.IsSelected)
{
selected.Add(s.ID);
}
}
return selected;
}
public IList<Int32> GetSelectedResults(IEnumerable<ZonesDto> zones)
{
IList<Int32> selected = new List<Int32>();
foreach (ZonesDto s in zones)
{
if (s.IsSelected)
{
selected.Add(s.ID);
}
}
return selected;
}
public IList<Int32> GetSelectedResults(IEnumerable<FaultAreasDto> faultAreas)
{
IList<Int32> selected = new List<Int32>();
foreach (FaultAreasDto s in faultAreas)
{
if (s.IsSelected)
{
selected.Add(s.ID);
}
}
return selected;
}
}
I have refactored it to use generics and a dynamic type for the loop but I'm still not happy with it
public IList<T> GetSelectedResults<T,U>(IEnumerable<U> scores)
{
List<T> selected = new List<T>();
foreach (dynamic s in scores)
{
if (s.IsSelected)
{
//Need to cast the ID as <T> due to the IList limitation below
//http://connect.microsoft.com/VisualStudio/feedback/details/534288/ilist-dynamic-cannot-call-a-method-add-without-casting
selected.Add((T)s.ID);
}
}
return selected;
}
Any other idea?
-
2\$\begingroup\$ Anything IEnuerable or IQueryable supports LINQ. If it isn't generic, you can call .Cast<Type>() first, then it's generic. \$\endgroup\$Lars-Erik– Lars-Erik2012年12月18日 10:59:40 +00:00Commented Dec 18, 2012 at 10:59
-
\$\begingroup\$ I agree with @Lars-Erik , Linq support all possible collection .you may consider using Extension method to write a clean code. \$\endgroup\$Paritosh– Paritosh2012年12月18日 11:04:31 +00:00Commented Dec 18, 2012 at 11:04
-
\$\begingroup\$ Yes, my mistake. I was missing the 'System.Linq' namespace for this class \$\endgroup\$Phil Murray– Phil Murray2012年12月18日 11:12:17 +00:00Commented Dec 18, 2012 at 11:12
1 Answer 1
Implement this interface in all of your Dto where it needed:
interface ICommonDtoStuff<T>
{
bool IsSelected { get; }
T ID { get; }
}
Then you can create a method like this:
public IList<T> GetSelectedResults<T, U>(IEnumerable<U> scores) where U : ICommonDtoStuff<T>
{
return scores.Where(x => x.IsSelected).Select(x => x.ID).ToList();
}
As extension method:
public static class Extensions
{
public static IList<T> GetSelectedResults<T>(this IEnumerable<ICommonDtoStuff<T>> scores)
{
return scores.Where(x => x.IsSelected).Select(x => x.ID).ToList();
}
}
-
\$\begingroup\$ Instead of generic
T
, you could useint
if you know the ID is always going to be of that type. \$\endgroup\$svick– svick2012年12月18日 13:40:10 +00:00Commented Dec 18, 2012 at 13:40