【问题标题】:Common .NET interface for a custom "ToString()" implementation provider?自定义“ToString()”实现提供程序的通用 .NET 接口?
【发布时间】:2015-05-13 15:15:14
【问题描述】:

我为一些单元测试编写了一个辅助方法,以使用自定义 IEqualityComparer<T> 实现来断言“集合等价”:

/// <summary>
/// Known issue: this checks for set-equality, which means that duplicate items will be interpreted as one.
/// </summary>
public static void AssertCollectionsAreEquivalent<T>(ICollection<T> expected, ICollection<T> actual,
        IEqualityComparer<T> comparer)
{
    T[] commonMembers = expected.Intersect(actual, comparer).ToArray();
    T[] missingMembers = expected.Except(actual, comparer).ToArray();
    T[] extraMembers = actual.Except(expected, comparer).ToArray();
    if (missingMembers.Any() || extraMembers.Any())
    {
        Assert.Fail("Collections were not equivalent.{0}Common members: {1}{0}Missing members: {2}{0}Extra members: {3}",
            Environment.NewLine,
            string.Join(", ", commonMembers.Select(t => t.ToString())),
            string.Join(", ", missingMembers.Select(t => t.ToString())),
            string.Join(", ", extraMembers.Select(t => t.ToString())));
    }
}

在此过程中,允许调用者提供可以提供自定义字符串格式的对象似乎很有帮助,但我没有看到 .NET 中符合要求的接口。我最终暂时使用了Func&lt;T, string&gt;

/// <summary>
/// Known issue: this checks for set-equality, which means that duplicate items will be interpreted as one.
/// </summary>
private static void AssertCollectionsAreEquivalent<T>(ICollection<T> expected, ICollection<T> actual,
    IEqualityComparer<T> comparer, Func<T, string> toStringConverter)
{
    T[] commonMembers = expected.Intersect(actual, comparer).ToArray();
    T[] missingMembers = expected.Except(actual, comparer).ToArray();
    T[] extraMembers = actual.Except(expected, comparer).ToArray();
    if (missingMembers.Any() || extraMembers.Any())
    {
        Assert.Fail("Collections were not equivalent.{0}Common members: {1}{0}Missing members: {2}{0}Extra members: {3}",
            Environment.NewLine,
            string.Join(", ", commonMembers.Select(toStringConverter)),
            string.Join(", ", missingMembers.Select(toStringConverter)),
            string.Join(", ", extraMembers.Select(toStringConverter)));
    }
}

这样做的动机是一个单元测试套件,它使用一个通用的测试 DTO 从数据存储中检索项目,但我们对不同的测试场景有不同的相等定义(因此IEqualityComparer&lt;T&gt; 参数)。我知道我可以定义一个自定义界面来做我想做的事:

public interface IToStringProvider<in T>
{
    string ToString(T obj);
}

...但我希望可能有一些现有的项目可以满足要求。

【问题讨论】:

  • 你听说过Enumerable.SequenceEquals吗?
  • 是的,但这会检查序列相等(相同的项目,相同的顺序),我真的只想要集合平等(相同的项目,任何顺序)。我知道我的示例实现了集合相等;我会在以后更新它,以便正确处理重复的项目。
  • 不确定为什么有人会对此投反对票。似乎措辞良好,代码示例等......

标签: .net interface string-formatting


【解决方案1】:

看看IFormattable。它可能会做你想做的事,尽管方式不尽相同。您可能需要在该方法上添加类型约束,但您会发现很多类型已经实现了这一点。

【讨论】:

  • 这是一个有趣的想法,但如果我理解正确的话,它需要 DTO 来实现 IFormattable,并且我希望能够根据不同的定义提供 DTO 的不同字符串表示形式平等。也许这表明一个常见的 DTO 不是解决这个问题的最佳方法......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多