LINQ
| Namespace | System.Linq |
|---|---|
| Category | Querying collections |
| In Unity | Sorting high scores, filtering inventories, finding the closest enemy |
LINQ
LINQ (Language Integrated Query) is a set of methods for asking questions about collections: "which items are weapons?", "sort enemies by distance", "what's the total value?". Each is one readable line instead of a hand-written loop. Add using System.Linq;.
A conveyor belt in a factory. Items go in one end. Where is a worker who throws out items that don't pass inspection. Select is a worker who repackages each item into something else. OrderBy sorts them. At the end, ToList() puts everything into a box for you. Nothing moves until someone at the end asks for the result.
Most-used methods
| Method | Does | Example |
|---|---|---|
Where(x => ...) | Keep items that match | items.Where(i => i.isWeapon) |
Select(x => ...) | Turn each item into something else | enemies.Select(e => e.name) |
OrderBy / OrderByDescending | Sort by a value | scores.OrderByDescending(s => s.points) |
First() / FirstOrDefault() | First item (throws / returns default if none) | items.FirstOrDefault(i => i.id == id) |
Any(x => ...) | Does at least one match? | enemies.Any(e => e.IsBoss) |
All(x => ...) | Do all match? | switches.All(s => s.isOn) |
Count(x => ...) | How many match? | items.Count(i => i.isKey) |
Sum, Min, Max, Average | Math over values | items.Sum(i => i.weight) |
Take(n) / Skip(n) | Only the first n / all but the first n | sorted.Take(10) (top 10) |
Distinct() | Remove duplicates | tags.Distinct() |
ToList() / ToArray() | Run the query and store the result | sorted.Take(10).ToList() |
Code Samples
Top 5 high scores
using System.Collections.Generic;
using System.Linq;
List<ScoreEntry> top5 = allScores
.OrderByDescending(s => s.points)
.Take(5)
.ToList();
Inventory questions
bool hasKey = inventory.Any(i => i.type == ItemType.Key);
float totalWeight = inventory.Sum(i => i.weight);
var potions = inventory.Where(i => i.type == ItemType.Potion).ToList();
string[] itemNames = inventory.Select(i => i.displayName).ToArray();
Closest enemy (the loop version is better in Update)
// LINQ: clear, fine for occasional use (e.g. when the player presses "lock on")
Enemy closest = enemies
.OrderBy(e => (e.transform.position - transform.position).sqrMagnitude)
.FirstOrDefault();
// Loop: no garbage, faster, better if it runs every frame
Enemy best = null;
float bestDist = float.MaxValue;
foreach (Enemy e in enemies)
{
float d = (e.transform.position - transform.position).sqrMagnitude;
if (d < bestDist) { bestDist = d; best = e; }
}
What happens at runtime
- Deferred execution:
Where,SelectandOrderBydon't do anything yet. They build a recipe. The work happens when you loop over it or callToList(),First(),Count(), etc. - If you loop over the same un-stored query twice, it runs twice. Store it with
ToList()if you'll reuse it. - Each LINQ call creates small objects (the query, the lambda, an enumerator), which is garbage. Harmless once, noticeable if done every frame on many objects.
Common Mistakes
- LINQ in Update on hot paths. Use it for menus, loading, events and editor tools; use loops for per-frame code. See Optimizing Your Code.
First()on an empty result throwsInvalidOperationException. UseFirstOrDefault()and check for null.- Destroyed Unity objects in the list.
enemies.Where(e => e != null)uses Unity's!=, which is correct. Avoide is not nullhere.
See also
- Collections
- Delegates, Lambdas & Events (what
x => ...means)
This page is a simplified, AI-assisted interpretation. For the complete and authoritative reference, see the official Microsoft C# documentation.