Subclass-specific static member data

家住魔仙堡 提交于 2020-01-07 05:58:25

问题


I'm trying to implement a family of classes who keep track of how many instances exist on a per-class basis. Because all of these classes have this behavior, I'd like to pull it out into a single superclass so I don't have to repeat the implementation with each class. Consider the following code:

class Base
{
    protected static int _instances=0;
    protected int _id;

    protected Base()
    {
        // I would really like to use the instances of this's class--not
        // specifically Base._instances
        this._id = Base._instances;
        Base._instances++;
    }
}

class Derived : Base
{
                                // Values below are desired,
                                // not actual:
    Derived d1 = new Derived(); // d1._id = 0
    Derived d2 = new Derived(); // d2._id = 1
    Derived d3 = new Derived(); // d3._id = 2

    public Derived() : base() { }
}

class OtherDerived : Base
{
                                            // Values below are desired,
                                            // not actual:
    OtherDerived od1 = new OtherDerived();  // od1._id = 0
    OtherDerived od2 = new OtherDerived();  // od2._id = 1
    OtherDerived od3 = new OtherDerived();  // od3._id = 2

    public OtherDerived() : base() { }
}

How can I achieve a per-class instance counter (one that is separate from the base class's counter)? I've tried mixing static & abstract (doesn't compile). Please advise.


回答1:


No, you can't do that. But you can have a static Dictionary<Type, int> and find out the type at execution time by calling GetType.

class Base
{
    private static readonly IDictionary<Type, int> instanceCounterMap
        = new Dictionary<Type, int>();
    protected int _id;

    protected Base()
    {
        // I don't normally like locking on other objects, but I trust
        // Dictionary not to lock on itself
        lock (instanceCounterMap)
        {
            // Ignore the return value - we'll get 0 if it's not already there
            instanceCounterMap.TryGetValue(GetType(), out _id);
            instanceCounterMap[GetType()] = _id + 1;    
        }
    }
}



回答2:


I would suggest that rather than trying to get a class to count instances of itself you create a factory class that manages the lifetimes of the instances. Rather than newing a 'OtherDerived' you implement a OtherDerivedFactory with a Build or Create method to serve them up. Internally, it can count instances.

Heck, abstract it a bit more with an interface and then you can inject the factory at run-time. Great for testing, alternate implementations, etc.



来源:https://stackoverflow.com/questions/13631652/subclass-specific-static-member-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!