正确地实现两个具有不同类型但在语义上等效的对象的比较

jay*_*jay 10 c# design-patterns design-principles

我发现了类似的问题

如何比较具有相似属性的两个截然不同的对象

这可能含蓄地和/或部分地回答了我的问题.

假设我想要比较(没有很多嵌套条件)这个对象:

class ObjectA {
  public string PropertyX { get; set; }
  public char PropertyY { get; set; }
  public long PropertyZ { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

到了System.String.我只对平等不平等感兴趣(不是关于身份的一系列价值观).

实施IEquatable<string>ObjectA是一个正确的选择吗?我不关心什么只是简单的工作,我想确定这种情况的正确模式.

作为其他信息,请考虑ObjectA通常按顺序提供IEnumerable<ObjectA>.

我不需要知道是否"string" ==!= objectA实例; 不涉及排序.

编辑以澄清(和帮助)

对不起,写一个好问题有时很难......

假设我不能将其表示ObjectA为字符串以进行比较(违反封装不是一种选择).

  • 在上下文中,我要与之匹配PropertyY.

  • 在context-2中,我要将它与应用于PropertyY/ 的算法相匹配PropertyZ.

@Oliver解决方案在问题的最后再次帮助我(再次+1).我可以简单地定义一个自定义界面:

interface IContextConverter {
  string ToEquatableStringForContext1();
  string ToEquatableStringForContext2();  
}
Run Code Online (Sandbox Code Playgroud)

由于我也有一个ObjectB相同的逻辑但不同的属性,两者都将实现IContextConverter(或者我找到一个更好的名称)避免违反RAP.

Oli*_*ver 6

我强烈建议不要实现IEquatable<string>,特别是在处理集合,字典,LINQ等时,你真的不知道何时会在其中某个方法中调用其中一个方法,这可能导致细微的错误.

由于您喜欢比较两种不同类型的对象,因此简单Comparer<T>也不行.

因此要么编写一个TypeConverter将对象转换为所需类型(在您的情况下为a string)或向对象添加方法,.ToEquatableString()并使用其输出将对象与其他字符串进行比较.

下面是一个示例,您可以获取与另一个集合中的一个字符串匹配的所有元素:

IEnumerable<String> otherElements = new[] {"abc", "def", "ghi" };
IEnumerable<ObjectA> myObjects = GetObjects();

var matchesFound = otherElements.Join( // Take the first collection.
              myObjects, // Take the second collection.
              s => s, // Use the elements in the first collection as key (the string).
              obj => obj.ToEquatableString(),  // Create a string from each object for comparison.
              (s, obj) => obj, // From the matching pairs take simply the objects found.
              StringComparer.OrdinalIgnoreCase); // Use a special string comparer if desired.
Run Code Online (Sandbox Code Playgroud)

  • @jay:不.它返回一个代表`objectA`的字符串.所以基本上像`.ToString()`一样.此字符串可以像任何其他字符串一样用于比较. (2认同)