Skip to content

[Proposal] For String/NullableString allow specifying StringComparer for use in source generation #99

@espenrl

Description

@espenrl

String comparison can be

  • CurrentCulture
  • CurrentCultureIgnoreCase
  • InvariantCulture
  • InvariantCultureIgnoreCase
  • Ordinal
  • OrdinalIgnoreCase

Please see https://learn.microsoft.com/en-us/dotnet/api/system.stringcomparison for more details.

It would be a great enhancement to StronglyTypedId if one could specify which one to use.


This is the source generated for a string (for the latest version of StronglyTypedId).

readonly partial struct OrderId : System.IComparable<OrderId>, System.IEquatable<OrderId>
{
    public string Value { get; }

    public OrderId(string value)
    {
        Value = value ?? throw new System.ArgumentNullException(nameof(value));
    }

    public static readonly OrderId Empty = new OrderId(string.Empty);

    public bool Equals(OrderId other)
    {
        return (Value, other.Value) switch
        {
            (null, null) => true,
            (null, _) => false,
            (_, null) => false,
            (_, _) => Value.Equals(other.Value),
        };
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
            return false;
        return obj is OrderId other && Equals(other);
    }

    public override int GetHashCode() => Value.GetHashCode(StringComparison.OrdinalIgnoreCase);

    public override string ToString() => Value;
    public static bool operator ==(OrderId a, OrderId b) => a.Equals(b);
    public static bool operator !=(OrderId a, OrderId b) => !(a == b);
    public int CompareTo(OrderId other)
    {
        return (Value, other.Value) switch
        {
            (null, null) => 0,
            (null, _) => -1,
            (_, null) => 1,
            (_, _) => Value.CompareTo(other.Value),
        };
    }
}

And this is how it could look like with StringComparison.OrdinalIgnoreCase. Note the changes in Equals(OrderId other), CompareTo(OrderId other) and GetHashCode(). The null checks are not needed when using string.Equals and string.Compare.

readonly partial struct OrderId : System.IComparable<OrderId>, System.IEquatable<OrderId>
{
    public string Value { get; }

    public OrderId(string value)
    {
        Value = value ?? throw new System.ArgumentNullException(nameof(value));
    }

    public static readonly OrderId Empty = new OrderId(string.Empty);

    public bool Equals(OrderId other)
    {
        return string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
            return false;
        return obj is OrderId other && Equals(other);
    }

    public override int GetHashCode() => Value.GetHashCode();

    public override string ToString() => Value;
    public static bool operator ==(OrderId a, OrderId b) => a.Equals(b);
    public static bool operator !=(OrderId a, OrderId b) => !(a == b);
    public int CompareTo(OrderId other)
    {
        return string.Compare(Value, other.Value, StringComparison.OrdinalIgnoreCase);
    }
}

The StronglyTypedIdAttribute would need a new option to specify the StringComparison and possibly also StronglyTypedIdDefaultsAttribute.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions