您需要问自己的第一件事是:
“如果我有两个 ID == 53 的仪器,那么这是否意味着它们绝对是相同的仪器,无论如何?或者是否存在有意义的案例,它们可能不同?”
假设答案是“它们都是相同的。如果任何其他属性不同,那要么是一个错误,要么是因为一个这样的对象是一个接一个地获得的,并且很快就会自行解决(当任何处理线程使用旧仪器时) ,停止使用它)”然后:
首先,在内部,只使用你觉得更方便的任何东西。int
尽管坚持将 anInstrument
传递给方法,但您很可能会发现这是一直存在的。如果所有Instrument
构造都发生在通过工厂方法访问的构造函数internal
或private
构造函数中,则尤其如此,并且代码的用户无法创建具有Instrument
与系统中任何内容都不匹配的 id 的虚假代码。
像这样定义相等:
public class Instrument : IEquatable<Instrument>
{
/* all the useful stuff you already have */
public bool Equals(Instrument other)
{
return other != null && Id == other.Id;
}
public override bool Equals(object other)
{
return Equals(other as Instrument);
}
public override int GetHashCode()
{
return Id;
}
}
现在,特别是当我们考虑到上述内容可能在大多数情况下被内联时,关于我们是否在相等性方面使用 ID 或对象几乎没有实现差异,因此在将它们用作关键。
现在,您可以通过以下任何方式定义所有公共方法:
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
return instrumentInfos[instrument];
}
或者:
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
return instrumentInfos[instrument.Id];
}
或者:
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
return GetInstrumentInfo(instrument.Id);
}
private InstrumentInfo GetInstrumentInfo(int instrumentID)
{
return instrumentInfos[instrumentID]
}
无论您选择哪种方式,性能影响都是一样的。呈现给用户的代码将是类型安全的,并保证它们不会传入虚假值。选择的实现可以简单地是由于其他原因您认为更方便的实现。
由于在内部使用仪器本身作为密钥不会再花费您,我仍然建议您这样做(上面三个选项中的第一个)作为类型安全并使其难以传递虚假值然后也将适用于您的内部代码。另一方面,如果您发现一组调用仍然只使用 id(例如,如果他们正在与只有 ID 有意义的数据库层交谈),那么仅更改这些位置对您来说变得快速而容易,并且对用户隐藏。
您还可以让您的用户能够使用您的对象作为键并进行快速的相等比较,如果它适合他们这样做的话。