C#
anonymous types
C# programming
.NET
coding practices

Returning anonymous type in C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, anonymous types are convenient for local projections, especially in LINQ, but they are not meant to be a stable public return type. You can technically return one as object or dynamic, but once you do that, you give up most of the compile-time benefits that made anonymous types attractive in the first place.

Why Anonymous Types Do Not Make Good Public Return Types

Anonymous types are compiler-generated and scoped around the place where they are inferred. The caller cannot declare a variable of that exact anonymous type explicitly unless it is working in the same local inference context.

That is why this is awkward:

csharp
1public object BuildSummary()
2{
3    return new { Name = "Ada", Age = 30 };
4}

The method compiles, but the caller only knows it is getting an object unless it falls back to reflection or dynamic.

dynamic Works, but Weakens the Contract

You can return an anonymous type through dynamic.

csharp
1public dynamic BuildSummary()
2{
3    return new { Name = "Ada", Age = 30 };
4}

This lets the caller write result.Name, but the checks now happen at runtime instead of compile time. That makes the API more fragile and harder to refactor safely.

Better Alternatives: Records, Classes, or Tuples

If the shape matters outside one local method, define a named type or use a tuple.

csharp
1public record Summary(string Name, int Age);
2
3public Summary BuildSummary()
4{
5    return new Summary("Ada", 30);
6}

Or for a lighter-weight option:

csharp
1public (string Name, int Age) BuildSummary()
2{
3    return ("Ada", 30);
4}

These approaches communicate intent much more clearly than hiding the return value behind object.

Where Anonymous Types Still Shine

Anonymous types are still excellent for:

  • local LINQ projections,
  • temporary grouping keys,
  • internal transformation steps inside one method.
csharp
var items = customers.Select(c => new { c.Name, c.City });

In that kind of local scope, var plus anonymous types is concise and expressive.

Design Rule: Return Contracts Should Be Explicit

If a method crosses a layer boundary, library boundary, or public API boundary, the return shape should usually be named and explicit. Anonymous types are strongest when they stay local and disposable.

That is the real answer to the question. It is not whether returning one is technically possible. It is whether doing so creates a good contract.

Anonymous Types Are Great Inside Query Pipelines

The place anonymous types really excel is inside a method where several small projections lead to a final explicit result. They let you express intermediate shapes without introducing a named DTO for every transformation step. The key is that those shapes should usually disappear before the method boundary, not leak out as the official return type.

Common Pitfalls

  • Returning an anonymous type as object and forcing callers to use reflection or guesses.
  • Returning dynamic and losing compile-time safety for no strong reason.
  • Using anonymous types beyond the short-lived projection scenarios they were designed for.
  • Avoiding tiny named DTOs or records even when the data shape clearly deserves one.
  • Confusing what is technically legal with what makes a maintainable API.

Summary

  • Anonymous types are convenient for local projections, not strong public method contracts.
  • Returning them through object or dynamic works, but weakens type safety and clarity.
  • Named records, classes, or tuples are usually better return types.
  • Anonymous types are best kept inside a local scope where var can infer them naturally.
  • Good API design favors explicit contracts over clever temporary shapes.

Course illustration
Course illustration

All Rights Reserved.