Asked  7 Months ago    Answers:  5   Viewed   59 times

Is there some rare language construct I haven't encountered (like the few I've learned recently, some on Stack Overflow) in C# to get a value representing the current iteration of a foreach loop?

For instance, I currently do something like this depending on the circumstances:

int i = 0;
foreach (Object o in collection)
{
    // ...
    i++;
}

 Answers

61

The foreach is for iterating over collections that implement IEnumerable. It does this by calling GetEnumerator on the collection, which will return an Enumerator.

This Enumerator has a method and a property:

  • MoveNext()
  • Current

Current returns the object that Enumerator is currently on, MoveNext updates Current to the next object.

The concept of an index is foreign to the concept of enumeration, and cannot be done.

Because of that, most collections are able to be traversed using an indexer and the for loop construct.

I greatly prefer using a for loop in this situation compared to tracking the index with a local variable.

Tuesday, June 1, 2021
 
Dev
answered 7 Months ago
Dev
17

That's basically what you need to do - or at least, it's the easiest solution. All you'd be "wasting" is the cost of n method invocations - you won't actually be checking any case twice, if you think about it. (IndexOf will return as soon as it finds the match, and you'll keep going from where it left off.)

Wednesday, June 2, 2021
 
Eugenie
answered 6 Months ago
78

You should use the Select function if you want to get a different result.

var items = listBox1.Items.Cast<string>().ToList();
listBox1.Items = items.Select(item => (!chkBox1.Checked) ? "move " + item : "move -check " + item).ToList();

The ForEach function can do something according to a collection value, but can't do it to the values themselves.

The Select function will create a new collection according to the given collection.

Edit

About your edit of successfully changing values by using

tapes.ForEach(x => x.vItem = "tapelib 3592 -eject " + x.vItem);

You need to understand how passing argument by value/reference works.

In c#, when writing var obj1 = new object(), obj1 is a pointer to the new object() that exists on the heap.

When you pass obj1 to a function public void Foo(object obj) { //... } by calling Foo(obj1), the function will get the parameter as new pointer to the same object on the heap.

Therefore, when you use ForeEach on the object itself,

object.ForEach(obj => obj = new object()) // No changed outside the Foreach

only the new pointer will be changed and it will point on a new object but the original pointer isn't changed.

But if you use it on an inner object,

object.ForEach(obj => obj.InnerObject = new object()) // Changed outside the Foreach

this will change the pointed inner object and the inner object will be changed.

Saturday, August 14, 2021
 
tika
answered 4 Months ago
58

foreach is not a standard C++ feature. This was something Eric Roberts and I developed for the Stanford introductory programming sequence and predates the more modern C++11 range-based for loop. Now that C++11 compiler support is more widespread, we've stopped using foreach and just opted to go with the standard C++ enhanced for loop.

I would generally not advice using foreach going forward as it's nonstandard. However, if you're compiling older code that uses it, you'll need to include one of the header files from the Stanford C++ Libraries that defines it.

Thursday, August 26, 2021
 
Naveen
answered 3 Months ago
88

You can get the virtual path to the file from one of several server variables - try either:

  • Request.ServerVariables("PATH_INFO")
  • Request.ServerVariables("SCRIPT_NAME")

(but not INSTANCE_META_PATH as previously suggested - this gives you the meta base path, not the virtual path you're expecting).

Either server variable will give you the virtual path including any sub-directories and the file name - given your example, you'll get "/virtual_directory/subdirectory/file.asp". If you just want the virtual directory, you'll need to strip off everything after the second forward slash using whatever method you prefer for plucking a directory out of a path, such as:

s = Request.ServerVariables("SCRIPT_NAME")
i = InStr(2, s, "/")
If i > 0 Then
    s = Left(s, i - 1)
End If

or:

s = "/" & Split(Request.ServerVariables("SCRIPT_NAME"), "/")(1)
Tuesday, October 5, 2021
 
AsGoodAsItGets
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share