MFTV0009: Do not mix tagged values with untagged values

edit

Cause

This rule is only reported in strict mode, enabled with taggedvalues.strict = true in the .editorconfig file.

A tagged value is compared with an untagged value, or flows from or to an untagged declaration:

public sealed class Order
{
    [ValueTag("OrderId")] public Guid Id { get; set; } = Guid.NewGuid(); // ok, a new value
}

public sealed class OrderService
{
    private readonly Guid _other = Guid.NewGuid();

    public void M(Order order)
    {
        _ = order.Id == _other;     // MFTV0009, compared with an untagged value
        order.Id = _other;          // MFTV0009, an untagged value flows to a tagged declaration
        Load(order.Id);             // MFTV0009, a tagged value flows to an untagged declaration
        _ = order.Id == Guid.Empty; // ok
    }

    private static void Load(Guid id) { }
}

Default values, null, constants, and Guid.Empty are allowed, and so are new values, such as the result of Guid.NewGuid(), when they flow to a tagged declaration. See What is allowed.

How to fix

Tag the untagged declaration. The code fix adds the tag to it:

public sealed class OrderService
{
    [ValueTag("OrderId")] private readonly Guid _other = Guid.NewGuid();

    public void M(Order order)
    {
        _ = order.Id == _other;
        order.Id = _other;
        Load(order.Id);
    }

    private static void Load([ValueTag("OrderId")] Guid id) { }
}