472,961 Members | 2,087 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,961 software developers and data experts.

Creating generic Isolator<T> class for collection modidy inside foreach loop

Code below causes error in class definition line

.....Isolator<T>' does not implement interface member
'System.Collections.IEnumerable.GetEnumerator()'.
'Myapp.Isolator<T>.GetEnumerator()' cannot implement
'System.Collections.IEnumerable.GetEnumerator()' because it does not have
the matching return type of 'System.Collections.IEnumerator'.

I tried to change method signature to

public IEnumerator GetEnumerator()

bu this causes another error

....Isolator<T>' does not implement interface member
'System.Collections.Generic.IEnumerable<T>.GetEnum erator()'.
'Myapp.Isolator<T>.GetEnumerator()' cannot implement
'System.Collections.Generic.IEnumerable<T>.GetEnum erator()' because it does
not have the matching return type of
'System.Collections.Generic.IEnumerator<T>'.

How to make this code work ?

Andrus.

using System;
using System.Collections;
using System.Collections.Generic ;

public class Isolator<T: IEnumerable<T>
{
IEnumerable<Tinner;

public Isolator(IEnumerable<Tenumerable)
{
inner = enumerable;
}

public IEnumerator<TGetEnumerator()
{
ArrayList<Tlist = new ArrayList<T>();
foreach (object o in inner)
list.Add(o);
return list.GetEnumerator();
}
}

Jun 27 '08 #1
8 2494
Because IEnumerable<Tderives from IEnumerable, you need to provide
*both* forms of GetEnumerator(); this is usually dona via explicit
implementation... just add:

IEnumerator IEnumerable.GetEnumerator()
{ // reuse typed enumerator
return GetEnumerator();
}

Marc
Jun 27 '08 #2
Marc,

Thank you. It works.
I'm planning to use it to remove members in linq invoice rows like

foreach (var row in new Isolator<TRow>(rowBindingSource))
{
if (row.Item == "VAT" || row.Item == "ROUNDING")
rowBindingSource.Remove(row);
}

Where rowBindingSource type is your linq TableList class.

Is this best style ?

In VFP I can use SQL directly from my application code

DELETE FROM rowBindingSource WHERE rows IN ("VAT", "ROUNDING")

Why Linq to Objects requires to create loop manually, .i.e forces me to use
procedural programming ?
Why there is no delete command in linq or method like

rowBindingSource.Remove( row=row.Item == "VAT" || row.Item ==
"ROUNDING" );

or

from row in rowBindingSource
where row=row.Item in ( "VAT", "ROUNDING" )
delete row;

Andrus.

Jun 27 '08 #3
On Jun 5, 10:39 am, "Andrus" <kobrule...@hot.eewrote:
Code below causes error in class definition line
<snip>

Marc has provided the reason why this fails, and a fix - but if you're
using C# 3 and .NET 3.5, you can just call ToList() on any
IEnumerable<Tand it'll have *nearly* the same effect - the main
difference being the time of copying. If that's an issue, consider an
extension method:

public static IEnumerable<TCopyLazily(this IEnumerable<Tsource) {
List<Tlist = source.ToList();
foreach (T t in list)
{
yield return t;
}
}

It makes life a lot simpler :)

Jon
Jun 27 '08 #4
On Jun 5, 11:23 am, "Andrus" <kobrule...@hot.eewrote:
Thank you. It works.
I'm planning to use it to remove members in linq invoice rows like

foreach (var row in new Isolator<TRow>(rowBindingSource))
{
if (row.Item == "VAT" || row.Item == "ROUNDING")
rowBindingSource.Remove(row);
}

Where rowBindingSource type is your linq TableList class.

Is this best style ?
Well, I'd just use:

foreach (var row in rowBindingSource.ToList())
{
...
}

Alternatively you could put a call to Where after .ToList() and remove
every matching row in the loop.
In VFP I can use SQL directly from my application code

DELETE FROM rowBindingSource WHERE rows IN ("VAT", "ROUNDING")

Why Linq to Objects requires to create loop manually, .i.e forces me to use
procedural programming ?
LINQ is designed to be side-effect free. Deleting is a side-effect.
Moreover, LINQ to Objects is based on IEnumerable, which has no notion
for deleting. What would you expect to happen if you tried to delete
from an array, for example?

Jon
Jun 27 '08 #5

"Andrus" <ko********@hot.eewrote in message
news:eu**************@TK2MSFTNGP03.phx.gbl...
Marc,

In VFP I can use SQL directly from my application code

DELETE FROM rowBindingSource WHERE rows IN ("VAT", "ROUNDING")

Why Linq to Objects requires to create loop manually, .i.e forces me to
use
procedural programming ?
Why there is no delete command in linq or method like

rowBindingSource.Remove( row=row.Item == "VAT" || row.Item ==
"ROUNDING" );

or

from row in rowBindingSource
where row=row.Item in ( "VAT", "ROUNDING" )
delete row;
The Q in LINQ stands for Query.

DELETE is not a query, it modifies the stored data.
--
Anthony Jones - MVP ASP/ASP.NET
Jun 27 '08 #6
Well, even indirectly, mixing enumeration and editing (removal) of a
list is not a greate idea.

Re the difference between SQL delete and .NET version; well, LINQ is
object orientated (SQL isn't); if you want to do anything in LINQ, you
do it to the instances. This is no different. Apart from this, there are
also issues like:
* concurrency management - hard to do on a block delete
* identity: if the data-context issues a block delete, how does it know
which records the database actually deleted? to update it's own local
cache of objects...
* LINQ can be configured to to the CRUD through SPs; how would it issue
a block-delete through a DELETE sproc that only accepts a PKID?

If this is going to be doing a lot of work, then I would create an SP
and call that (you can expose SPs with arguments etc to LINQ-to-SQL very
easily).

If you are dealing with smaller volumes, and you want a Remove(fn) on
some local class, then just add one!

Marc
Jun 27 '08 #7
Well, I'd just use:
>
foreach (var row in rowBindingSource.ToList())
{
...
}

Alternatively you could put a call to Where after .ToList() and remove
every matching row in the loop.
Thank you. Delete needs to scan over whole collection always.
So I changed foreach to use ToArray()

foreach (var row in rowBindingSource.ToArray() )
{
if (row.Item == "VAT" || row.Item == "ROUNDING")
rowBindingSource.Remove(row);
}

hope this faster than ToList().

Is it reasonable/how to create generic static method which implements this
mass-Remove() for IList<Tcollections ?
Since covariant types are not supported in C#, generic type parameter should
be used probably.

Andrus.

Jun 27 '08 #8
On Jun 5, 1:33 pm, "Andrus" <kobrule...@hot.eewrote:
Alternatively you could put a call to Where after .ToList() and remove
every matching row in the loop.

Thank you. Delete needs to scan over whole collection always.
Yes, but if you are only *acting* on certain elements, you can call
Where() to only get those items:

var toDelete = rowBindingSource.Where(row =row.Item=="VAT" ||
row.Item=="ROUNDING").ToList();
foreach (var row in toDelete)
{
rowBindingSource.Remove(row);
}
So I changed foreach to use ToArray()
<snip>
hope this faster than ToList().
I'd expect it to be slower in some cases, actually - because it needs
to accurately count the number of items before creating the array.
Is it reasonable/how to create generic static method which implements this
mass-Remove() for IList<Tcollections ?
Yes, that would be easy to do as an extension method.
Since covariant types are not supported in C#, generic type parameter should be used probably.
Absolutely.

Just offhand (untested):

public static void RemoveWhere<T(this IList<Tsource, Func<T,bool>
predicate)
{
List<TtoRemove = source.Where(predicate).ToList();
foreach (T t in toRemove)
{
source.Remove(t);
}
}

Jon
Jun 27 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: ESPNSTI | last post by:
Hi, I'm trying to use a generics dictionary with a key class that implements and needs IComparable<>. However when I attempt to use the dictionary, it doesn't appear to use the IComparable<> to...
15
by: Gustaf | last post by:
Using VS 2005. I got an 'IpForm' class and an 'IpFormCollection' class, containing IpForm objects. To iterate through IpFrom objects with foreach, the class is implemented as such: public class...
4
by: Michel Walsh | last post by:
Hi, A datagrid has its DataSource set to a BindingList<CustomClass>. While the ListChanged event fires AFTER a deletion, I am looking for a simple way to be notified BEFORE the item would be...
20
by: martin-g | last post by:
Hi. Mostly I program in C++, and I'm not fluent in C# and .NET. In my last project I began to use LinkedList<and suddenly noticed that can't find a way to sort it. Does it mean I must implement...
0
by: Iron Moped | last post by:
I'm airing frustration here, but why does LinkedList<not support the same sort and search methods as List<>? I want a container that does not support random access, allows forward and reverse...
3
by: =?Utf-8?B?TGFtYm9yZ2hpbmk=?= | last post by:
Hi, I am coming back to programming in C#, and perhaps I never came accross this. Can someone point me in the right direction to research about them. For instance, what do they mean in the...
22
by: amygdala | last post by:
Hi, I'm trying to grasp OOP to build an interface using class objects that lets me access database tables easily. You have probably seen this before, or maybe even built it yourself at some...
44
by: Zytan | last post by:
The docs for List say "The List class is the generic equivalent of the ArrayList class." Since List<is strongly typed, and ArrayList has no type (is that called weakly typed?), I would assume...
2
by: =?Utf-8?B?Unlhbg==?= | last post by:
Hi, How can I get around runtime error that says I can not explicit cast List<SubClassto ICollection<Class>? Generic List inhertis generic ICollection and Subclass inherits Class, then...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.