# Value Objects

A Value Object represents a conceptually whole value with no identity. It is defined solely by its attributes or properties and is considered immutable, meaning its state cannot be changed after creation. Two Value Objects with the same attributes are considered equal, regardless of their individual identities.<br>

Characteristics of Value Objects:

1. **Immutability**: Once created, the state of a Value Object cannot be modified. Any changes to its properties result in a new Value Object instance.
2. **Equality based on attributes**: Value Objects are compared based on the equality of their attributes rather than their identities.
3. **Side-effect-free**: Value Objects should not have any behavior or actions associated with them. They are primarily used to hold and model data.
4. **Lightweight**: Since Value Objects are immutable and do not have identities, they are typically lightweight and easy to copy.
5. **Replaceable**: If two Value Objects have the same attributes, they can be replaced with each other without any impact on the domain logic.

{% hint style="info" %}
**Eiffel.Modelling.Abstractions** NuGet package contains base ValueObject class. By using abstract ValueObject class you can define your value objects.
{% endhint %}

```csharp
 /// <summary>
 /// Value object
 /// </summary>
 /// <typeparam name="T">The type of value object class</typeparam>
 public abstract class ValueObject<T> where T : ValueObject<T>
 {
     /// <inheritdoc/>
     public override bool Equals(object obj)
     {
         if (obj == null || GetType() != obj.GetType())
             return false;

         T other = (T)obj;
         return GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
     }

     /// <inheritdoc/>
     public override int GetHashCode()
     {
         return GetEqualityComponents()
             .Aggregate(17, (current, obj) => current * 23 + (obj?.GetHashCode() ?? 0));
     }

     /// <inheritdoc/>
     protected abstract IEnumerable<object> GetEqualityComponents();
 }
```

*Example Location value object.*

```csharp
public class Location : ValueObject<Location>
{
    public string City { get; }

    public string Country { get ;}

    public Location(string city, string country)
    {
        City = city;
        Country = country;
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.eiffel.dev/principles/domain-driven-design/value-objects.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
