Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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?

share|improve this question
2  
Anything IEnuerable or IQueryable supports LINQ. If it isn't generic, you can call .Cast<Type>() first, then it's generic. –  Lars-Erik Dec 18 '12 at 10:59
    
I agree with @Lars-Erik , Linq support all possible collection .you may consider using Extension method to write a clean code. –  paritosh Dec 18 '12 at 11:04
    
Yes, my mistake. I was missing the 'System.Linq' namespace for this class –  Phil Murray Dec 18 '12 at 11:12
add comment

1 Answer 1

up vote 2 down vote accepted

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();
    }
}
share|improve this answer
    
Instead of generic T, you could use int if you know the ID is always going to be of that type. –  svick Dec 18 '12 at 13:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.