私有静态列表是限制类

时间:2017-07-28 13:52:35

标签: c# static factory protected

我试图避免使用相同的内部数据创建类的多个实例。我尝试使用单独的类来构建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实例。

2 个答案:

答案 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更复杂,我只需实现一个具有值相等语义的私有嵌套结构/类,并将其用作字典的键。