ทั้ง C++ (C++11+) และ C# รองรับ Range-based for Loop (foreach) แต่มีความแตกต่างใน Syntax และ Semantics
C++ Range-based for Loop (C++11)
#include <iostream>
#include <vector>
#include <string>
int main()
{
// Array
int arr[] = { 99, 15, 67 };
for (int elem : arr)
std::cout << elem << '\n';
// Vector
std::vector words = { "Hello", "World" };
for (const auto& w : words) // const reference - ไม่ copy
std::cout << w << ' ';
// Modify elements
for (auto& w : words) // reference - แก้ไขได้
w += "!";
return 0;
}
C# foreach Statement
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// Array
int[] arr = { 99, 15, 67 };
foreach (int elem in arr)
Console.WriteLine(elem);
// List
var words = new List { "Hello", "World" };
foreach (var w in words)
Console.WriteLine(w);
// Dictionary
var dict = new Dictionary { ["a"] = 1, ["b"] = 2 };
foreach (var kvp in dict)
Console.WriteLine($"{kvp.Key} = {kvp.Value}");
// String (char sequence)
foreach (char c in "Hello")
Console.Write(c + " ");
}
}
ผลลัพธ์ C#
99
15
67
Hello
World
a = 1
b = 2
H e l l o
ตารางเปรียบเทียบ
| คุณสมบัติ | C++ Range-for | C# foreach |
|---|---|---|
| Syntax | for (type var : range) | foreach (type var in collection) |
| รองรับ Type | Array, Container (begin/end), Initializer List | IEnumerable<T>, Array, String |
| Modification | ได้ด้วย Reference (auto&) | ไม่ได้ (Iteration Variable Read-only) |
| Index Access | ไม่มีโดยตรง | ไม่มีโดยตรง (ใช้ for ปกติ) |
| Break/Continue | รองรับ | รองรับ |
| Performance | Zero Overhead (Compile-time) | Virtual Call (IEnumerator) - มี Overhead น้อย |
| Custom Iteration | Implement begin()/end() | Implement IEnumerable<T> / IEnumerator<T> |
C# foreach รายละเอียดเพิ่มเติม
- Iteration Variable เป็น Read-only - ไม่สามารถ Assign ให้ได้
- ใช้
IEnumerator<T>ภายใน - เรียกMoveNext()และCurrent IDisposablePattern: Enumerator จะ Dispose อัตโนมัติหลัง Loop จบ- รองรับ
yield returnใน Iterator Method
C++17 Structured Binding (Bonus)
std::map map = { {"a", 1}, {"b", 2} };
for (const auto& [key, value] : map) // Structured Binding
std::cout << key << "=" << value << '\n';
C# 7+ Deconstruction (คล้าย Structured Binding)
var dict = new Dictionary { ["a"] = 1, ["b"] = 2 };
foreach (var (key, value) in dict) // Deconstruction
Console.WriteLine($"{key} = {value}");