views:

43

answers:

1

In RIA services the EntityCollection<T> class is defined as follows :

public sealed class EntityCollection<TEntity> : IEntityCollection, 
                                                IEnumerable<TEntity>, 
                                                IEnumerable,  
                                                INotifyCollectionChanged,  
                                                INotifyPropertyChanged where TEntity :  
                                                global::System.ServiceModel.DomainServices.Client.Entity

I have a Silverlight converter which sets Visibility dependent upon the number of items in a list.

 if (value is EntityCollection<CustomerFeedbackDetail>)
 {
      visible = (value as EntityCollection<CustomerFeedbackDetail>).Count > 0;
 }

But wait - I want it to be generic for any EntityCollection. Uh oh - IEntityCollection is internal and not accessible to us. EntityCollection doesn't even implement ICollection.

Am I stuck without using reflection (which I really would rather not do since this may get called many times a second in some cases).

I'm pretty sure I do have to use reflection to make this generic - so in that case why would IEntityCollection be internal? Oversight?

+3  A: 

Rather than using reflection, you could just implement the function yourself. You don't care about the count, just that it's non-zero. Simply rewrite the Enumberable.Any(IEnumerable<T>) function to take non-generic IEnumerable:

public static bool Any(this System.Collections.IEnumerable source)
{
    if (source == null)
        throw new ArgumentNullException("source");

    return source.GetEnumerator().MoveNext();
}

Then in your converter you would have:

if (value is EntityCollection<CustomerFeedbackDetail>) 
{ 
    visible = (value as IEnumerable).Any(); 
} 
Gabe
it didn't like the 'using', but works apart from that! thanks!ps. what kind of exception handling mechanism are you using to have Error.ArgumentNull ?
Simon_Weaver
some interesting notes on 'Any()' vs 'Count' from Phil Haack : http://haacked.com/archive/2010/06/10/checking-for-empty-enumerations.aspx
Simon_Weaver
The original code was just a copy of `Enumberable.Any(IEnumerable<T>)` with the `<T>` removed. Since `IEnumerable` doesn't implement `IDisposable`, the `using` didn't belong. I fixed the code and eliminated external dependencies.
Gabe
@Gabe: Good answer, however you should test whether the `Enumerator` returned by `GetEnumerator` implements `IDisposable` and dispose the `Enumerator` if it does.
AnthonyWJones