我试图避免使用相同的内部数据创建类的多个实例。我尝试使用单独的类来构建MCode,但尝试保护MCode构造函数不起作用,所以我回到了这个实现。我想知道这是好的设计还是可能有更好的解决方案?
public class MCode : IEquatable<MCode>
{
private readonly static List<MCode> Instances;
public AEnum AE { get; }
public byte C { get; }
public BEnum BE { get; }
public static MCode GetMCode(AEnum ae, BEnum be, byte c)
{
if (Instances==null)
{
Instances = new List<MCode>();
var newmc = new MCode(ae, be, c);
Instances.Add(newmc);
return newmc;
}
var mc = Instances.Find(x => x.Equals(ae, be, c));
if (mc == null)
{
var newmc = new MCode(ae, be, c);
Instances.Add(newmc);
return newmc;
}
return mc;
}
protected MCode(AEnum ae, BEnum be, byte c)
{
AE = ae;
BE = be;
C = c;
}
public new bool Equals(MCode mc)
{
return (GetHashCode() == mc.GetHashCode());
}
public new bool Equals(AEnum ae, BEnum be, byte c)
{
return (GetHashCode() == GetHashCode(ae, be, c));
}
public new int GetHashCode()
{
return ((byte)AE * 256 * 256 + (byte)BE * 256 * C);
}
public static int GetHashCode(AEnum ae, BEnum be, byte c)
{
return ((byte)ae * 256 * 256 + (byte)be * 256 * c);
}
}
这样做的动机是我有多个包含相同MCode属性的类实例,并且我希望它们都使用相同的只读MCode实例。
答案 0 :(得分:4)
您所描述的内容似乎是Flyweight Factory pattern。 Flyweights是相对较小的类,并且存在有限数量的“唯一”对象,因此维护唯一实例的目录可以帮助减少内存中不必要的重复数据。
一个例子是US State
。只有50个唯一状态,因此将50个状态的集合保存为一组唯一实例可能会对系统产生影响,例如,每个用户记录都需要一个状态。
我也会将班级与工厂分开。将工厂设为一个单独的类,并为MCode
internal
(而不是protected
创建构造函数。
我也会小心你的Equals
实施。仅仅因为两个对象具有相同的哈希码并不意味着它们是相等的。在您的情况下可能是这样,因为int
空间可以覆盖有限数量的对象,但它看起来很奇怪。实现实际 Equals
逻辑(您已经在列表查找中使用的逻辑)也将无需重复的GetHashCode
方法。
答案 1 :(得分:2)
您可以使用工厂方法和静态字典来实现此目的:
public class MyType
{
private readonly static Dictionary<int, MyType> instances
= new Dictionary<int, MyType>();
public static MyType CreateNew(int id)
{
if (instances.TryGetValue(id, out var instance)
return instance;
return new MyType(id);
}
private MyType(int id) { ... }
public int UniqueId { get; }
}
如果您的唯一标识符比int
更复杂,我只需实现一个具有值相等语义的私有嵌套结构/类,并将其用作字典的键。