1
\$\begingroup\$

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?

asked Dec 18, 2012 at 9:57
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Anything IEnuerable or IQueryable supports LINQ. If it isn't generic, you can call .Cast<Type>() first, then it's generic. \$\endgroup\$ Commented 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\$ Commented Dec 18, 2012 at 11:04
  • \$\begingroup\$ Yes, my mistake. I was missing the 'System.Linq' namespace for this class \$\endgroup\$ Commented Dec 18, 2012 at 11:12

1 Answer 1

2
\$\begingroup\$

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();
 }
}
answered Dec 18, 2012 at 11:00
\$\endgroup\$
1
  • \$\begingroup\$ Instead of generic T, you could use int if you know the ID is always going to be of that type. \$\endgroup\$ Commented Dec 18, 2012 at 13:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.