RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

foreach & for

Hawkins

Sorceror
foreach & for

They are abit confusing for me, in Hashtable(), ArrayList() and List<T>.

private Hashtable m_Items = new Hashtable();
private ArrayList m_Mobiles = new ArrayList();
private List<object> m_ItemsNMobiles = new List<object>();

  1. As for the above, is there any preference that whether foreach or for shall be used?
  2. I notice ( perhaps I am wrong? ), sometimes it doesn't need guard from null reference, some other times however, guarding from null reference is needed. So when and why it is needed or not needed.

PHP:
if ( m_Items != null && m_Items.Count > 0 )		// null reference guard
{
	for ( int i = 0; i < m_Items.Count; i++ )
	{
		
	}
}

if ( m_Items != null && m_Items.Count > 0 )		// null reference guard
{
	foreach ( Item item in m_Items.Values )
	{
		
	}
}
 
'foreach' loops look nicer and spare you from confusion in the rare case of a non-zero-based collection. There is some evidence that supports a performance gain from 'for' loops but this is negligible.

You should always make sure an object's initialized before doing anything with it. I've never seen a null check on a collection because typically you don't plan to iterate through a collection you haven't initialized. Regardless, you don't need to check the count on a 'foreach.'
 

Jeff

Lord
Ya the for loops are faster, but only on ultra high frequency code (for instance 60+ fps games). I personally always use them, but foreach loops come in handy for prototyping and simplicity.
 

Hawkins

Sorceror
Thanks so much, Suil Ban and Jeff.

So I might need to change my coding practice to reduce the null checking unless it's very necessary. :)
 

Jeff

Lord
Hawkins;801053 said:
Thanks so much, Suil Ban and Jeff.

So I might need to change my coding practice to reduce the null checking unless it's very necessary. :)

The standard rule is, if it could in anyway be null at any time even if the possibility is 0.0001% you should add a null check, otherwise, don't. Generally if something is null, and shouldn't be, you should let it crash, so you can find out why and fix it. Adding tons of if(blank != null) can have an ill effect if you don't intend for an object to ever be null, and for some reason it is.
 

Hawkins

Sorceror
Jeff;801075 said:
The standard rule is, if it could in anyway be null at any time even if the possibility is 0.0001% you should add a null check, otherwise, don't. Generally if something is null, and shouldn't be, you should let it crash, so you can find out why and fix it. Adding tons of if(blank != null) can have an ill effect if you don't intend for an object to ever be null, and for some reason it is.

Agree 100% and understand now. Searching the up-stream for the problems instead of sealing the down-stream with a protection. :)

Thanks very much.
 

arul

Sorceror
Foreach loops are great in conjuction with fluent interfaces and/or iterators. In .NET 2.0 it's power is kinda limited, but it's true nature unleashes with extension methods/LINQ in .NET 3.5.

Consider the following example which selects all bandages that have more than 20 stack-items, hue 1122 and were moved in the last 10 minutes:

.NET 2.0:

Code:
List<Item> bandages = 
     backpack[FONT=monospace].FindItemsByType<Bandage>(delegate(Item item){ return (item.Amount > 20) && (item.Hue == 1122) && ((DateTime.Now - [/FONT][FONT=monospace]item.LastMoved[/FONT][FONT=monospace]) < TimeSpan.FromMinutes(10)); });[/FONT]
.NET 3.5:

Code:
IEnumerable<Item> bandages = 
      backpack.FindItemsByType<Bandage>()
        .AmountGreaterThan(20)
        .HueEquals(1122)
        .LastMovedIn(10.Minutes());
Performance of both snippets is virtually equal, plus the latter is much more readable and self-explanatory.
 

Jeff

Lord
arul;801141 said:
Foreach loops are great in conjuction with fluent interfaces and/or iterators. In .NET 2.0 it's power is kinda limited, but it's true nature unleashes with extension methods/LINQ in .NET 3.5.

Consider the following example which selects all bandages that have more than 20 stack-items, hue 1122 and were moved in the last 10 minutes:

.NET 2.0:

Code:
List<Item> bandages = 
     backpack[FONT=monospace].FindItemsByType<Bandage>(delegate(Item item){ return (item.Amount > 20) && (item.Hue == 1122) && ((DateTime.Now - [/FONT][FONT=monospace]item.LastMoved[/FONT][FONT=monospace]) < TimeSpan.FromMinutes(10)); });[/FONT]
.NET 3.5:

Code:
IEnumerable<Item> bandages = 
      backpack.FindItemsByType<Bandage>()
        .AmountGreaterThan(20)
        .HueEquals(1122)
        .LastMovedIn(10.Minutes());
Performance of both snippets is virtually equal, plus the latter is much more readable and self-explanatory.

I have a love hate relationship with the last one. I love extension methods, but i don't know if I like the look of the crazy method syntax...me being picky, but it looks so, not C#...
 

arul

Sorceror
Jeff;801145 said:
I have a love hate relationship with the last one. I love extension methods, but i don't know if I like the look of the crazy method syntax...me being picky, but it looks so, not C#...
And it's gonna be even worse with C# 4.0 :) I have mixed feelings about fluent interfaces too, but they're really addictive.
 

Hawkins

Sorceror
arul;801141 said:
Foreach loops are great in conjuction with fluent interfaces and/or iterators. In .NET 2.0 it's power is kinda limited, but it's true nature unleashes with extension methods/LINQ in .NET 3.5.

Consider the following example which selects all bandages that have more than 20 stack-items, hue 1122 and were moved in the last 10 minutes:

.NET 2.0:

Code:
List<Item> bandages = 
     backpack[FONT=monospace].FindItemsByType<Bandage>(delegate(Item item){ return (item.Amount > 20) && (item.Hue == 1122) && ((DateTime.Now - [/FONT][FONT=monospace]item.LastMoved[/FONT][FONT=monospace]) < TimeSpan.FromMinutes(10)); });[/FONT]
.NET 3.5:

Code:
IEnumerable<Item> bandages = 
      backpack.FindItemsByType<Bandage>()
        .AmountGreaterThan(20)
        .HueEquals(1122)
        .LastMovedIn(10.Minutes());
Performance of both snippets is virtually equal, plus the latter is much more readable and self-explanatory.

:eek: They are total strangers to me.

I know that it's still a long road for me to go. :(
 

Jeff

Lord
arul;801147 said:
And it's gonna be even worse with C# 4.0 :) I have mixed feelings about fluent interfaces too, but they're really addictive.

Ya, I can't help but feel extremely left and right on the whole C# 4.0 thing. I mean, I know they are juts making things easier to code and read, but almost at a price of making C# look like some low tech scripting language.
 

Hawkins

Sorceror
arul;801141 said:
.NET 2.0:

Code:
List<Item> bandages = 
     backpack[FONT=monospace].FindItemsByType<Bandage>(delegate(Item item){ return (item.Amount > 20) && (item.Hue == 1122) && ((DateTime.Now - [/FONT][FONT=monospace]item.LastMoved[/FONT][FONT=monospace]) < TimeSpan.FromMinutes(10)); });[/FONT]

Does the snippet mean to look for an overloaded function "FindItemsByType" with a signature of parameter ( Item item ) and a return type of bool dynamiclaly at runtime ( delegate )? :confused:

Or perhaps looking for a overloaded function named "FindItemsbyType" with "Type" as paramenter and return type of "Item"?


Thanks very much. I am curious. :p
 

arul

Sorceror
My bad, the delegate code should actually read: delegate(Bandage item). The function accepts a Predicate<T>, which is used as a general purpose filtering function:
Code:
delegate bool Predicate<T>(T obj);

The FindItemsByType<T> function iterates over the backpack, if it finds an item of the type T the predicate function is invoked for that item, and if the result is true the object is added to the resulting collection.
 

Peoharen

Sorceror
I thought 2.0 had LINQ, *shurgs* I've never really used it outside of a really plain and simple almost rip off of msdn's example.

How would
Code:
var bandages = from band in backpack.FindItemsByType<Bandage>()
where band.Amount > 20
where band.Hue == 1122
select band;
Work compared to for/foreach?
 

Jeff

Lord
Unfortunately LINQ queries have proven to be a bit slower then a foreach/for loop. I really enjoy LINQ for its ability to allow me to turn 15 lines of code into 1-3. But when you are looking for speed, it is not a great alternative.
 

Tartaros

Wanderer
Hawkins;800910 said:
They are abit confusing for me, in Hashtable(), ArrayList() and List<T>.

private Hashtable m_Items = new Hashtable();
private ArrayList m_Mobiles = new ArrayList();
private List<object> m_ItemsNMobiles = new List<object>();

for a Hashtable/Dictionary/LinkedList/AnyOtherCollectionThatIsNotContinuouslyIndexedByNature you need foreach whether you want or not.

In case of ArrayList/List<> using a simple for (int i=0, n = list.Count; i<n; i++) { ... } will probably run slightly faster than foreach, because you're omitting the overhead of several method calls in each iteration, even though the basic principle will be the same.
Plus you have the advantage that you can modify (the size of) the list, if you know what you're doing :)

In an array (like Object[]), a foreach block will be expanded to a for block similar to the above one by the compiler, so it's totally irrelevant which one you use
 

Jeff

Lord
You dont need forloops for indexed collections, you CAN use while loops on their enumerators.
 

Tartaros

Wanderer
Jeff;834714 said:
You dont need forloops for indexed collections, you CAN use while loops on their enumerators.

i didn't say you need forloops for indexed collections.

But ofc you can always use "while", that's basically what both for and foreach are expanded into by the compiler, so yes you can do that manually. Altho it's usually less easy on the eye :)
 

Jeff

Lord
Tartaros;834718 said:
i didn't say you need forloops for indexed collections.

But ofc you can always use "while", that's basically what both for and foreach are expanded into by the compiler, so yes you can do that manually. Altho it's usually less easy on the eye :)

I wasnt talking to you directly, hence why i didn't quote you.
 
Top