Link to home
Start Free TrialLog in
Avatar of pzozulka
pzozulka

asked on

C#.NET: loop through a collection to filter out items

I have a collection called CurrentAddressCollection which I need to loop through to filter out certain items, and then return that same collection. However, this filter should only apply when a certain condition is true, otherwise just return the collection as is.

I thought about using LINQ, like my example below, but it didn't work because LINQ returns an IEnumerable<Address> collection which is not the same type as the CurrentAddressCollection. And when I try to cast the IEnumerable collection as DomainList it returns null.

Question:
After using linq to filter out a collection, how do I get my collection to be of the same type before linq was applied?


...
gridAddresses.DataSource = GetDataSource().ToArray();
...

private DomainList GetDataSource()
{
	if (CurrentAddressCollection.ListOwner is CustomerQuote)
	{
		var addresses = CurrentAddressCollection.Cast<Address>().Where(a => a.AddressName != "ABC");
		return addresses as DomainList;
	}

	return CurrentAddressCollection;
}

public AddressHack CurrentAddressCollection
{
	get{return _currentAddressCollection;}
	set{_currentAddressCollection = value;}
}

Open in new window


More Info:
AddressHack is an abstract class that inherits from DomainList.

DomainList is an abstract class that has the ToArray() method:
public virtual DomainObject[] ToArray()
{
	return (DomainObject[]) List.ToArray(typeof(DomainObject));
}

Open in new window

Avatar of chuang4630
chuang4630

Have you thought about the AutoMapper?
ASKER CERTIFIED SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@kaufmed
and then return that same collection

Am I missing something?
I dunno...  I had a little trouble following the code supplied, but I thought "same collection" meant the same type of CurrentAddressCollection. Regardless of the type, if it's not List or array, then custom code is needed.

And if he indeed means to filter the existing collection, then removing the items as you suggest is feasible.
First in place, what is the connection between AddressHack  and Address? The CurrentAddressCollection is of type AddressHack. But you cast it to Address.

Assuming that all elements of CurrentAddressCollection are compatible with DomainList. If so, try..
var addresses = CurrentAddressCollection.Cast<DomainList>().Where(a => a.AddressName != "ABC");

Open in new window


If only few elements are compatible with DomainList then try below...

var addresses = CurrentAddressCollection.OfType<DomainList>().Where(a => a.AddressName != "ABC");

Open in new window


Otherwise try below...

var addresses = CurrentAddressCollection.OfType<Address>().Where(a => a.AddressName != "ABC");
return addresses as DomainList;

Open in new window


HTH.
Avatar of pzozulka

ASKER

käµfm³d: Your understanding was correct in that after applying the linq code, I was hoping to get the same TYPE of collection back, instead of an IEnumerable.

Easwaran Paramasivam: The relationship is as follows:

public AddressHack CurrentAddressCollection { get; set; }

public abstract class AddressHack : DomainList, IAddressHack
{
   ...
}

public class AddressCollection<T> : AddressHack where T : Address, new()
{
   ...
}

Here's the code I tried to debug:
// ToArray() is a virtual method in the DomainList class. 
// CurrentAddressCollection is a "AddressHack", and "AddressHack" is a "DomainList"
grdAddresses.DataSource = GetDataSource().ToArray(); 
grdAddresses.DataBind();

private DomainList GetDataSource()
{
	if (condition == true)
	{
		var a = CurrentAddressCollection.OfType<Address>().Where(a => a.AddressName != "ABC");
		var b = a as DomainList;
		return b;
	}

	return CurrentAddressCollection;
}

Open in new window

After executing the linq code, a contains an IEnumerable collection of type <Address>. After executing the following line, b is null.
>>then return that same collection.
In future please ask for what you want.  You are now asking for a different (new) collection to be returned.

Just what is the collection?  If it is a List then you could make a clone then use RemoveAll as I suggested previously.
For clone:
http://stackoverflow.com/questions/222598/how-do-i-clone-a-generic-list-in-c

eg.
var newList = oldList.ToList();
Andy, as of now, it seems that your solution seems to be the only one that would work, but at this point, I'm just trying to learn to see if the original collection type (less filtered out items) can be returned using the linq code above.

I use linq often, particularly in this context, to filter collections. From what I've gathered here, this is not possible without custom code.
I try not to use linq if I can do it easily by traditional ways.  (I can usually rapidly scan and see errors in code but as soon as I come to linq or delegates I have to stop and think hard just what it is doing and what it is meant to do - not necessarily the same).

Use tools appropriate to the job.