Rand Random
Rand Random

Reputation: 7440

Memberexpression on collection item

I am currently struggling to get a method done using a memberexpression on the items within a collection. I know how to write a memberexpression holding directly the member of the collection but how can I tell it to use its underlying type.

private Collection<TestClass> collection { get; set; }
DoSomethingWithCollection(collection, () => collection.Count);

private void DoSomethingWithCollection(Collection<TestClass> collection, MemberExpression member)
{
    foreach(var item in collection)
    {
        //use reflexion to get the property for each item 
        //based on the memberexpression and work with it
    }
}

How would I need to rewrite this code that the call of DoSomethingWithCollection can hold a Memberexpression of the underlying type of the collection, so from the "TestClass"?

Upvotes: 0

Views: 405

Answers (2)

Mike Strobel
Mike Strobel

Reputation: 25623

In your comments, you asked about setting properties as well. Perhaps what you are really looking for is a more generalized solution like a ForEach operator that performs some action for every element in a collection:

public static void ForEach<TSource>(
    this IEnumerable<TSource> source,
    Action<TSource> action)
{
    if (source == null)
        throw new ArgumentNullException("source");
    if (action== null)
        throw new ArgumentNullException("action");

    foreach (TSource item in source)
        action(item);
}

Now you could read a property:

items.ForEach(item => Console.WriteLine(item.Name));

...or set a property:

items.ForEach(item => item.Name = item.Name.ToUpper());

...or do anything else:

items.ForEach(item => SaveToDatabase(item));

You could write this extension method yourself, but it also a part of the Interactive Extensions, which extends LINQ with several features from the Reactive Extensions. Just look for the "Ix Experimental" package on NuGet.

Upvotes: 1

Thomas C. G. de Vilhena
Thomas C. G. de Vilhena

Reputation: 14565

You could use generics to achieve that more easily and efficiently:

private void DoSomethingWithCollection<TClass, TProperty>(
    Collection<TClass> collection,
    Func<TClass, TProperty> extractProperty)
{
    foreach (var item in collection)
    {
        var value = extractProperty(item);
    }
}

Here is how you'd use it (considering your collection items have a "Name" property):

DoSomethingWithCollection(collection, item => item.Name);

Upvotes: 3

Related Questions