Converting IEnumerable<int?> to IEnumerable<int> in C#: All Four Options Explained
C# provides four methods that enable users to transform an IEnumerable containing nullable integer values into non-nullable integer…
C# & LINQ
Converting IEnumerable<int?> to IEnumerable<int> in C#: All Four Options Explained
C# provides four methods that enable users to transform an IEnumerable containing nullable integer values into non-nullable integer formats. Each method interprets the meaning of null values differently — here’s how to pick the right one.

Source : Nagaraj
The compiler error message demonstrates an explicit issue: you have an IEnumerable collection that contains nullable int values yet the subsequent process needs an IEnumerable collection that contains only non-nullable int values. The solution to the problem appears simple. The C# programming language provides four different methods to manage null data, yet this fact makes it harder because each method brings its own understanding of what null values mean.
The system will execute without errors when an incorrect option is selected. The system operates incorrectly because it does not display missing records and deletes essential information, while its aggregation process silently applies standard default values to rows that should have been excluded.
The article demonstrates all four available choices through practical examples which include the Entity Framework situation that frequently appears in actual production environments.

Why This Type Mismatch Happens

The most common place this bites developers is Entity Framework. You create a database query for a column that allows null values in the database. Your entity class uses EF to correctly model that column as a nullable integer. You send the output to a function that requires a non-nullable IEnumerable collection — perhaps a utility function, a service, or a LINQ chain that needs non-nullable integers for an ID lookup.
The compiler is pointing out the problem. Whether the null values get handled — and how — is your decision. The four options below each represent a different answer to that question.

What the error means: CS0266 — “Cannot implicitly convert type
IEnumerable<int?>toIEnumerable<int>." The compiler protects you because it cannot determine how to handle the null rows. Your decision needs to be made between the four options below, each of which presents a unique answer.

Option 1 — Filter and Unwrap with .Where + .Select
The present method represents the clearest way to accomplish the task. You first filter out all null entries with .Where, then project each surviving nullable int to its underlying int value with .Select. The output sequence only permits movement of values that existed as actual entities.

Why
x!.Value? The filter.Where(x => x.HasValue)shows that every element contains a value but the compiler remains unaware of this fact. The null-forgiving operator!informs the compiler that this variable will not be null at this location. The.Valuefunction then extracts theintvalue from theint?variable. You can achieve the same result without the null-forgiving operator by writing.Select(x => x.GetValueOrDefault())after the filter.

The option provides two advantages that establish it as the secure default choice for team codebases. The first point establishes complete readability because the filter step clearly communicates that nulls will not pass through the sequence. The two operations execute standard LINQ functions which will not surprise C# developers who read the code.
The first option should be selected when null values indicate no assigned user and unassigned orders must be excluded from downstream processing. It is the right choice when the team requires explicit and reviewable intent in the codebase, or when the sequence feeds an ID lookup, join, or aggregate that cannot process missing semantics.
Option 2 — Use .OfType <int> () for Clean Intent
You need to use this expression because it represents the most compact way to express your intention to remove null values. The function OfType limits its output to elements which match the designated type — and since null does not match the integer type, it is excluded from the results automatically.

How it works internally:
.OfType<int>()checks all elements using anispattern match. The method skips all elements that do not match the pattern, which includes null values. The remaining elements get converted tointand returned as results.
So additional types such as the select are not necessary; yet it is worth noting. The actual features of Option 1 are there in this statement too, while a single method chain forms the flow in this situation.

The second option presents a challenge because it makes discovery difficult for developers who haven’t encountered it before. The function OfType operates in this particular way which developers need to understand before they can read it fluently. Option 1 explains itself through code reviews and onboarding contexts while Option 2 requires users to understand how OfType handles null values specifically.
You should choose Option 2 when your team needs to remove null values while keeping their codebase streamlined which needs to be maintained by multiple developers who will read their utility code and for whom your team already knows LINQ patterns.
Option 3 — Replace Null with a Default Value
The term null should not always be interpreted as “exclude this item.” The term null should be understood to mean that “this item exists without a provided value, which should be treated as a known default.” The requirement states that all items must remain in the sequence while the missing values are replaced.

The null-coalescing operator x ?? 0 returns x.Value when x contains a value and returns 0 when x is null. The sequence length remains unchanged because each input element generates one output element. Your domain should use the appropriate default value which should replace 0 with -1 for “sentinel not found” and int.MinValue for “unknown” and all business-defined constants.

The selection method leads to hidden data damage which impacts system functionality. The output code fails to identify 0 as a missing value because it treats 0 as a standard ID and an actual count. The Entity Framework implementation will create a query which contains the UserId IN (0, 12, 45) condition that either produces no results because user 0 does not exist or matches incorrect records.
You should select Option 3 when the null value indicates an unassigned status and a sentinel value is permissible in subsequent processing. The consuming code needs to understand that 0 or the chosen default functions as a missing value indicator. The output should be directed to the count aggregate or display layer — not into a database query.
Option 4 — Re think the Receiving Type
The actual solution to the problem needs a different question which asks for the explanation of why a sequence must contain only non-null elements. The existing type mismatch demonstrates a design error because your domain permits null values as acceptable data yet the downstream system was developed with the assumption that null values would not occur.

When this is the right call: The presence of ?? 0 in your code only to filter out 0 at a later point, or downstream code with if (id != 0) guards scattered through it, indicates that the null value was not properly handled but instead was redirected to another part of the program. The type system correctly identifies the issue, and the solution requires contract updates according to option 4.
The implementation needs extensive effort because it requires two tasks which include updating method signatures and refactoring all call sites. The method produces the most accurate semantic results because it creates precise code outputs for systems that use nullability as a business-specific value which includes unassigned and optional and not-yet-known data types.
You should select Option 4 when three conditions are met: null values carry significance that requires full handling; you are creating or refactoring a permanent service boundary; and the downstream code needs to process optional values through direct, explicit methods.
Choosing the Right Option: A Decision Map


The Entity Framework Scenario Revisited
The EF query generates foreign keys which may appear as null values and these results need to be fixed. The database requires the predicate to be placed in the EF query before data retrieval occurs. The SQL statement generated by this procedure creates a WHERE AssignedUserId IS NOT NULL clause which prevents unnecessary data from being loaded into memory.
[embed]
EF Core tip: Push the null filter into the EF query before materializing:
context.Orders.Where(o => o.AssignedUserId != null).Select(o => o.AssignedUserId!.Value). The SQL output generates aWHERE AssignedUserId IS NOT NULLstatement which prevents any null records from being retrieved from the database.

The type system blocks implicit assignment because it requires complete data type information. The system requires you to declare all data quality decisions which will affect future system operations. You must resolve the error instead of hiding it from view.

The system provides four options which create four distinct interpretations of null within your dataset. Your sequence contains null values which need assessment to determine whether they represent absence or error or sentinel status or first-class value. The code will create itself after you answer that initial question.

Thank you for reading! 👏👏👏 Hit the applause button and show your love❤️, and please follow➡️ for a lot more similar content! Let’s keep the good vibes flowing!

메타데이터
- post_id
- 80d0f59ec331
- slug
- converting-ienumerable-int-to-ienumerable-int-in-c-all-four-options-explained-80d0f59ec331
- url
- https://towardsdev.com/converting-ienumerable-int-to-ienumerable-int-in-c-all-four-options-explained-80d0f59ec331
- canonical_url
- https://towardsdev.com/converting-ienumerable-int-to-ienumerable-int-in-c-all-four-options-explained-80d0f59ec331
- author_url
- https://medium.com/@nagarajvela
- status
- ok
- fetched_at
- 2026-06-18 07:02:39