Skip to content

Supported Types

Martin Zahálka edited this page Feb 12, 2026 · 1 revision

Supported Types

ZMapper handles all common .NET types out of the box. No special configuration is needed for these types — just use CreateMap and ForMember as usual.

Type Support Table

Category Types Notes
Primitives int, long, short, byte, sbyte, double, float, decimal, bool, char Direct assignment
Strings string Handles null, empty, unicode, and long strings
Date/Time DateTime, DateTimeOffset, DateOnly, TimeOnly, TimeSpan Full support including modern date types
Identifiers Guid, Uri Common identifier types
Enums All enum types Mapped by value (underlying integer)
Nullable Value Types int?, DateTime?, Guid?, MyEnum?, etc. Auto-handled with ?? default fallback
Nullable Reference Types string?, MyClass? Null-safe assignment
Collections List<T>, T[], IReadOnlyList<T>, IEnumerable<T> Via MapArray/MapList methods
Inheritance Base class properties (any depth) Automatic, no configuration needed
Records C# record types Full support
Init Setters init-only properties Generated code uses object initializer
Required Properties required keyword Generated code satisfies requirement

Primitives

All .NET primitive types are mapped with direct assignment:

public class Source
{
    public int Count { get; set; }
    public double Price { get; set; }
    public bool IsActive { get; set; }
    public char Grade { get; set; }
    public byte Level { get; set; }
}

public class Destination
{
    public int Count { get; set; }
    public double Price { get; set; }
    public bool IsActive { get; set; }
    public char Grade { get; set; }
    public byte Level { get; set; }
}

// All primitives mapped automatically by convention
config.CreateMap<Source, Destination>();

Date and Time Types

public class EventDto
{
    public DateTime StartTime { get; set; }
    public DateTimeOffset CreatedAt { get; set; }
    public DateOnly EventDate { get; set; }
    public TimeOnly StartAt { get; set; }
    public TimeSpan Duration { get; set; }
}

// All date/time types mapped automatically
config.CreateMap<EventDto, Event>();

Enums

Enums are mapped by their underlying value:

public enum OrderStatus { Created, Confirmed, Shipped, Delivered }
public enum PaymentMethod { Cash, CreditCard, BankTransfer, PayPal }

public class OrderDto
{
    public OrderStatus Status { get; set; }
    public PaymentMethod Payment { get; set; }
}

// Enums mapped automatically
config.CreateMap<OrderDto, Order>();

Nullable Value Types

When source has nullable types and destination has non-nullable types, ZMapper generates safe fallback code:

public class Source
{
    public DateTime? CreatedAt { get; set; }  // nullable
    public int? Count { get; set; }            // nullable
    public Guid? ExternalId { get; set; }      // nullable
}

public class Destination
{
    public DateTime CreatedAt { get; set; }   // non-nullable
    public int Count { get; set; }             // non-nullable
    public Guid ExternalId { get; set; }       // non-nullable
}

config.CreateMap<Source, Destination>();
// Generated: destination.CreatedAt = source.CreatedAt ?? default;
// Generated: destination.Count = source.Count ?? default;
// Generated: destination.ExternalId = source.ExternalId ?? default;

The ?? default fallback produces:

  • DateTime -> DateTime.MinValue (0001-01-01)
  • int -> 0
  • Guid -> Guid.Empty
  • bool -> false
  • etc.

Collections

Collections are mapped via the mapper's batch methods, not via CreateMap:

// Register the element mapping
config.CreateMap<PersonDto, Person>();

// Then use batch methods at runtime
Person[] array = mapper.MapArray<PersonDto, Person>(dtos.AsSpan());
List<Person> list = mapper.MapList<PersonDto, Person>(dtos);
List<Person> fromQuery = mapper.MapList<PersonDto, Person>(dtos.Where(d => d.IsActive));

Collection Properties on Objects

When a mapped object contains collection properties, ZMapper handles them automatically if the element type has a registered mapping:

public class OrderDto
{
    public List<OrderItemDto> Items { get; set; }
}

public class Order
{
    public List<OrderItem> Items { get; set; }
}

// Register both mappings
config.CreateMap<OrderItemDto, OrderItem>();
config.CreateMap<OrderDto, Order>();

// Items collection is mapped automatically
var order = mapper.Map<OrderDto, Order>(orderDto);
// order.Items contains mapped OrderItem objects

Modern C# Features

Records

public record PersonRecord(string Name, int Age);
public record PersonEntity(string Name, int Age);

config.CreateMap<PersonRecord, PersonEntity>();

Init-Only Properties

public class Product
{
    public string Name { get; init; }
    public decimal Price { get; init; }
}

// Generated code uses object initializer syntax
config.CreateMap<ProductDto, Product>();

Required Properties

public class User
{
    public required string Username { get; set; }
    public required string Email { get; set; }
}

// Generated code satisfies the 'required' constraint
config.CreateMap<UserDto, User>();

Type Conversion Notes

Scenario Behavior
Same types (int -> int) Direct assignment
Nullable to non-nullable (int? -> int) ?? default fallback
Non-nullable to nullable (int -> int?) Direct assignment (implicit conversion)
string? -> string Direct assignment with #pragma warning disable CS8601
Enum -> Enum (same type) Direct assignment
Complex types Requires registered mapping (nested mapping)

Next Steps

Clone this wiki locally